#include "mem_arena.h" #include "aliases.h" #include "mem_utils.h" #include #include #include #ifndef DEFAULT_ALIGNMENT // Why 2 * sizeof(void *) instead of sizeof(void *) // https://handmade.network/forums/t/6860-alignment_arena_allocator #define DEFAULT_ALIGNMENT (2 * sizeof(void *)) #endif /* ifndef DEFAULT_ALIGNMENT */ #define ARENA_MINIMUM_CAPACITY 1024 struct arena { u8 *buf; u8 *offset; u64 capacity; }; // PUBLIC API bool wapp_mem_arena_init(Arena **arena, u64 base_capacity) { if (!arena || *arena || base_capacity == 0) { return false; } *arena = (Arena *)calloc(1, sizeof(Arena)); Arena *arena_ptr = *arena; if (!arena_ptr) { return false; } u64 arena_capacity = base_capacity >= ARENA_MINIMUM_CAPACITY ? base_capacity : ARENA_MINIMUM_CAPACITY; arena_ptr->buf = (u8 *)calloc(arena_capacity, sizeof(u8)); if (!(arena_ptr->buf)) { wapp_mem_arena_destroy(arena); return false; } arena_ptr->capacity = arena_capacity; arena_ptr->offset = arena_ptr->buf; return true; } void *wapp_mem_arena_alloc(Arena *arena, u64 size) { return wapp_mem_arena_alloc_aligned(arena, size, DEFAULT_ALIGNMENT); } void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) { if (!arena) { return NULL; } u8 *alloc_start = arena->offset; u8 *output = wapp_mem_util_align_forward((void *)alloc_start, alignment); if (output + size >= arena->buf + arena->capacity) { return NULL; } arena->offset = output + size; memset(output, 0, size); return (void *)output; } void wapp_mem_arena_clear(Arena *arena) { if (!arena) { return; } memset(arena->buf, 0, arena->offset - arena->buf); arena->offset = arena->buf; } void wapp_mem_arena_destroy(Arena **arena) { if (!arena) { return; } Arena *arena_ptr = *arena; if (arena_ptr->buf) { free(arena_ptr->buf); } arena_ptr->buf = arena_ptr->offset = NULL; arena_ptr->capacity = 0; free(*arena); *arena = NULL; }