Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does posix_memalign/memalign do

I'm trying to understand what functions memalign() and posix_memalign() do. Reading the available documentation didn't help.

Can someone help me understand how it works and what is it used for? Or, perhaps provide a usage example?

I'm trying to understand how linux memory works, I need to write my own simple memory pool (low-fragmentation heap).

like image 814
artyomboyko Avatar asked Jul 03 '11 13:07

artyomboyko


People also ask

What is Posix_memalign used for?

DESCRIPTION. The posix_memalign() function shall allocate size bytes aligned on a boundary specified by alignment, and shall return a pointer to the allocated memory in memptr. The value of alignment shall be a power of two multiple of sizeof(void *).

What is aligned Alloc?

The aligned_alloc function allocates space for an object whose alignment is specified by alignment, whose size is specified by size, and whose value is indeterminate.

What is Valloc?

The obsolete function valloc() allocates size bytes and returns a pointer to the allocated memory. The memory address will be a multiple of the page size. It is equivalent to memalign(sysconf(_SC_PAGESIZE),size).

What is address alignment?

An aligned access is an operation where a word-aligned address is used for a word, dual word, or multiple word access, or where a halfword-aligned address is used for a halfword access. Byte accesses are always aligned.


2 Answers

Whereas malloc gives you a chunk of memory that could have any alignment (the only requirement is that it must be aligned for the largest primitive type that the implementation supports), posix_memalign gives you a chunk of memory that is guaranteed to have the requested alignment.

So the result of e.g. posix_memalign(&p, 32, 128) will be a 128-byte chunk of memory whose start address is guaranteed to be a multiple of 32.

This is useful for various low-level operations (such as using SSE instructions, or DMA), that require memory that obeys a particular alignment.

like image 86
Oliver Charlesworth Avatar answered Oct 02 '22 17:10

Oliver Charlesworth


malloc always returns memory that is set to the maximum alignment required by any of the primitive types. This allows malloc'd memory to store any type you may need. My understanding of the description of posix_memalign, is that it returns a memory location who's address will be a multiple of whatever you specify as the alignment.

Im not sure how useful this would be when writing a custom memory pool, but I have had a go at providing an example of how this could be implemented. The difference is with my example, anything allocated with malloc_aligned has to be freed with free_aligned; however, with posix_memalign you can use free.

#include <stdlib.h> #include <stdio.h>  void *malloc_aligned(size_t alignment, size_t bytes) {     // we need to allocate enough storage for the requested bytes, some      // book-keeping (to store the location returned by malloc) and some extra     // padding to allow us to find an aligned byte.  im not entirely sure if      // 2 * alignment is enough here, its just a guess.     const size_t total_size = bytes + (2 * alignment) + sizeof(size_t);      // use malloc to allocate the memory.     char *data = malloc(sizeof(char) * total_size);      if (data)     {         // store the original start of the malloc'd data.         const void * const data_start = data;          // dedicate enough space to the book-keeping.         data += sizeof(size_t);          // find a memory location with correct alignment.  the alignment minus          // the remainder of this mod operation is how many bytes forward we need          // to move to find an aligned byte.         const size_t offset = alignment - (((size_t)data) % alignment);          // set data to the aligned memory.         data += offset;          // write the book-keeping.         size_t *book_keeping = (size_t*)(data - sizeof(size_t));         *book_keeping = (size_t)data_start;     }      return data; }  void free_aligned(void *raw_data) {     if (raw_data)     {         char *data = raw_data;          // we have to assume this memory was allocated with malloc_aligned.           // this means the sizeof(size_t) bytes before data are the book-keeping          // which points to the location we need to pass to free.         data -= sizeof(size_t);          // set data to the location stored in book-keeping.         data = (char*)(*((size_t*)data));          // free the memory.         free(data);     } }  int main() {     char *ptr = malloc_aligned(7, 100);      printf("is 5 byte aligned = %s\n", (((size_t)ptr) % 5) ? "no" : "yes");     printf("is 7 byte aligned = %s\n", (((size_t)ptr) % 7) ? "no" : "yes");      free_aligned(ptr);      return 0; } 
like image 32
Node Avatar answered Oct 02 '22 16:10

Node