#include "arena.h" #include #include #include static bool is_power_of_two(uintptr_t x) { return (x & (x - 1)) == 0; } static uintptr_t align_forward(uintptr_t ptr, size_t alignment) { assert(is_power_of_two(alignment)); uintptr_t modulo = ptr & (alignment - 1); /* = ptr % alignment */ if (modulo != 0) ptr += alignment - modulo; return ptr; } void arena_init(Arena *arena, void *buffer, size_t buffer_length) { arena->buffer = buffer; arena->buffer_length = buffer_length; arena->offset = 0; } #ifndef DEFAULT_ALIGNMENT #define DEFAULT_ALIGNMENT (2 * sizeof(void *)) #endif void *arena_alloc(Arena *arena, size_t size) { return arena_alloc_align(arena, size, DEFAULT_ALIGNMENT); } void *arena_alloc_align(Arena *arena, size_t size, size_t alignment) { /* Align the current offset to the specified alignment */ uintptr_t curr_ptr = (uintptr_t)arena->buffer + arena->offset; uintptr_t offset = align_forward(curr_ptr, alignment); offset -= (uintptr_t)arena->buffer; /* Check to see if there is some memory left */ if (offset <= arena->buffer_length - size) { void *ptr = &arena->buffer[offset]; arena->offset = offset + size; /* Zero out newly allocated memory */ memset(ptr, 0, size); assert(ptr != 0); return ptr; } abort(); } void arena_clear(Arena *arena) { arena->offset = 0; }