I am trying to write a custom stack allocator for a game I am working on. To deal with memory alignment, I am using C11's stdalign.h header; however, since I do not have prior experience with alignment issues, I'd like a expert opinion on whether I am doing it right.
The majority of the alignment stuff happens in alignup and aligndown macros. Specifically, in alignup, I try to go up to the nearest multiple of alignof(max_align_t) (unless we were already a multiple) by shooting past it by adding alignof(max_align_t) - 1 and then coming back using the bitwise AND. In aligndown, I first go below the last multiple of alignof(max_align_t) and then come up using alignup.
NOTE: The stack is in a memory arena and it grows down in memory instead of going up.
#define alignup(p) ((void*)((((char*)(p)) + (alignof(max_align_t) - 1)) & (~ (alignof(max_align_t) - 1))))
#define aligndown(p) ((void*)(alignup((((char*)(p)) - (alignof(max_align_t) - 1)))))
struct Mem_Stack_Header {
size_t allocation_size;
size_t total_size;
};
// This contains the "head" of the stack. The stack grows down, instead of up.
extern void *stack_head;
void* memPush (size_t s)
{
void *head = stack_head;
void *mem = (char*)head - s;
mem = aligndown(mem);
struct Mem_Stack_Header *h = (struct Mem_Stack_Header*)((char*)mem - sizeof(*h));
h = aligndown(h);
h->allocation_size = s;
h->total_size = (uintptr_t)((char*)head - (char*)h);
stack_head = h;
return mem;
}
void memPop (void)
{
struct Mem_Stack_Header *h = stack_head;
stack_head = (char*)stack_head + h->total_size;
return;
}
Is this the correct way of doing this kind of stuff? Any improvements I can make?
internal_function? You don't seem to define it anywhere. \$\endgroup\$static.statichas so many meanings in C, I defineinternal_function,persistent_valueandglobal_variabletostaticto give some semantic context. \$\endgroup\$_Mem_Stack_Headeris reserved because it begins with an underscore immediately followed by a capital letter)? \$\endgroup\$memPush()andvoid *mem = (char*)head - s;as that is pointer arithmetic on an invalid pointer (stack_head == NULL). VTC \$\endgroup\$