Embedded Artistry libmemory
Memory library for embedded systems (malloc and friends)
aligned_malloc.c File Reference
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "aligned_malloc.h"
#include "malloc.h"
Include dependency graph for aligned_malloc.c:

Go to the source code of this file.

Macros

#define align_up(num, align)   (((num) + ((align)-1)) & ~((align)-1))
 
#define PTR_OFFSET_SZ   sizeof(offset_t)
 Macro for accessing the size of our current pointer offset. More...
 

Typedefs

typedef uint16_t offset_t
 Number of bytes we're using for storing the aligned pointer offset. More...
 

Functions

void * aligned_malloc (size_t align, size_t size)
 Allocated aligned memory. More...
 
void aligned_free (void *ptr)
 Free aligned memory. More...
 

Macro Definition Documentation

◆ align_up

#define align_up (   num,
  align 
)    (((num) + ((align)-1)) & ~((align)-1))

Simple macro for making sure memory addresses are aligned to the nearest power of two

Definition at line 21 of file aligned_malloc.c.

◆ PTR_OFFSET_SZ

#define PTR_OFFSET_SZ   sizeof(offset_t)

Macro for accessing the size of our current pointer offset.

Definition at line 28 of file aligned_malloc.c.

Typedef Documentation

◆ offset_t

typedef uint16_t offset_t

Number of bytes we're using for storing the aligned pointer offset.

Definition at line 25 of file aligned_malloc.c.

Function Documentation

◆ aligned_free()

void aligned_free ( void *  ptr)

Free aligned memory.

aligned_free works like free(), but we work backwards from the returned pointer to find the correct offset and pointer location to return to free() Note that it is VERY BAD to call free() on an aligned_malloc() pointer.

Definition at line 74 of file aligned_malloc.c.

75 {
76  assert(ptr);
77 
78  /*
79  * Walk backwards from the passed-in pointer to get the pointer offset
80  * We convert to an offset_t pointer and rely on pointer math to get the data
81  */
82  offset_t offset = *((offset_t*)ptr - 1);
83 
84  /*
85  * Once we have the offset, we can get our original pointer and call free
86  */
87  void* p = (void*)((uint8_t*)ptr - offset);
88  free(p);
89 }
uint16_t offset_t
Number of bytes we're using for storing the aligned pointer offset.
void free(void *__attribute__((unused)) ptr)
Definition: malloc_assert.c:23

References free().

◆ aligned_malloc()

void* aligned_malloc ( size_t  align,
size_t  size 
)

Allocated aligned memory.

We will call malloc with extra bytes for our header and the offset required to guarantee the desired alignment.

Definition at line 36 of file aligned_malloc.c.

37 {
38  void* ptr = NULL;
39 
40  // We want it to be a power of two since align_up operates on powers of two
41  assert((align & (align - 1)) == 0);
42 
43  if(align && size)
44  {
45  /*
46  * We know we have to fit an offset value
47  * We also allocate extra bytes to ensure we can meet the alignment
48  */
49  size_t hdr_size = PTR_OFFSET_SZ + (align - 1);
50  void* p = malloc(size + hdr_size);
51 
52  if(p)
53  {
54  /*
55  * Add the offset size to malloc's pointer (we will always store that)
56  * Then align the resulting value to the arget alignment
57  */
58  ptr = (void*)align_up(((uintptr_t)p + PTR_OFFSET_SZ), align);
59 
60  // Calculate the offset and store it behind our aligned pointer
61  *((offset_t*)ptr - 1) = (offset_t)((uintptr_t)ptr - (uintptr_t)p);
62 
63  } // else NULL, could not malloc
64  } // else NULL, invalid arguments
65 
66  return ptr;
67 }
void * malloc(size_t __attribute__((unused)) size)
Definition: malloc_assert.c:17
uint16_t offset_t
Number of bytes we're using for storing the aligned pointer offset.
#define PTR_OFFSET_SZ
Macro for accessing the size of our current pointer offset.
#define align_up(num, align)

References align_up, malloc(), and PTR_OFFSET_SZ.

Referenced by posix_memalign().

Here is the caller graph for this function: