#ifndef ARENA_H #define ARENA_H typedef enum { ARENA_ZERO = 1 << 0, ARENA_SOFTFAIL = 1 << 1, } arena_flags_t; // More or less taken from https://nullprogram.com/blog/2023/09/27/ typedef struct { uint8_t *begin; uint8_t *end; } arena_t; arena_t arena_create(ptrdiff_t capacity) { arena_t a = {0}; a.begin = malloc(capacity); a.end = a.begin ? a.begin + capacity : 0; return a; } void *arena_alloc(arena_t *a, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, arena_flags_t flags) { ptrdiff_t padding = -(uintptr_t)a->begin & (align - 1); ptrdiff_t available = a->end - a->begin - padding; if (available < 0 || count > available/size) { // TODO: Decide what to do on oom if (flags & ARENA_SOFTFAIL) return 0; else abort(); } void *p = a->begin + padding; a->begin += padding + count*size; return flags & ARENA_ZERO ? p : memset(p, 0, count*size); } #define arena_reserve(arena, type, count, flags) (type *)arena_alloc(arena, sizeof(type), _Alignof(type), count, flags) #define KB 1024 #define MB 1024*KB #define GB 1024*MB #endif