[fpc-pascal] memory aligning

David Pethes imcold at imcold.evilhosting.org
Mon Nov 5 11:03:18 CET 2007


Hi,
I'm writing a video codec. I need some of my memory aligned to 16-byte 
boundaries, since I'm using SSE2 instructions in asm code, that assume 
this alignment. I was using a custom getmem, that called classic getmem 
to get some memory block, then cast the pointer and adjust it to next 
aligned address. Offset to original pointer was saved as byte at 
(aligned_address - 1). Custom freemem took aligned pointer, read the 
address (ptr-1) to get the offset, set the original pointer address and 
call the classic freemem.
This worked well, though compiler was complaining about that casting the 
  pointer to int was not portable. I discovered the Align() function in 
system unit, so I modified the code like this:

function evk_malloc (size: longword): pointer;
const
   ALIGNMENT = 16;
begin
   result := GetMem(size + ALIGNMENT);
   result := Align (result, ALIGNMENT);
end;

procedure evk_free (ptr: pointer);
begin
   Freemem(ptr);
end;

I assumed that freemem will handle the aligned pointer correctly. This 
even worked for few weeks, until I added some more getmem/freemem in the 
code - started crashing on freemems. Even valgrind complained. I 
discovered that my assumption was false - I need to free the original 
pointer. So I mixed the two codes and come with something like this:

function evk_malloc (size: longword): pointer;
const
   ALIGNMENT = 16;
var
   ptr: pointer;
begin
   ptr := getmem(size + ALIGNMENT);
   result := Align (ptr, ALIGNMENT);
   if result = ptr then
       pbyte(result) += 16;
   //store offset to original address
   (pbyte(result) - 1)^ := result - ptr;
end;

procedure evk_free (ptr: pointer);
begin
   if ptr = nil then exit;
   //adjust to original address
   pbyte(ptr) -= pbyte(ptr-1)^ ;
   freemem(ptr);
end;

Is this correct to use? Wouldn't be there any catches for example when 
running on 64-bit machine?

Also, does FPC support aligning stack variables and record members on 
mod16 addresses like GCC 
(http://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/Variable-Attributes.html#Variable-Attributes)
? I would like to have an array inside a rather huge record that starts 
at aligned address for SSE2 use, too.

Best regards,

David





More information about the fpc-pascal mailing list