From ba471f41b72c311ede0698aba2e7364e086b0ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Wed, 10 Jun 2026 16:43:22 +0200 Subject: [PATCH] Update mini arena --- src/main.c | 11 ++--- src/mini_arena.h | 110 +++++++++++++++++++++++------------------------ 2 files changed, 60 insertions(+), 61 deletions(-) diff --git a/src/main.c b/src/main.c index ccd3f8f..81d801d 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include "base_core.h" #include "arena.h" +#include "mini_arena.h" #include "platform.h" #include #include @@ -91,12 +92,12 @@ static void arena_test_2(void) ((U8*)ptr)[0] = 0x73; ptr = arena_push(&arena, 0, KB(4)); //((U8*)ptr)[0] = 0x73; - arena_reset_to(&arena, 1089); + // arena_reset_to(&arena, 1089); arena_dump(&arena); arena_reset_to(&arena, 0); - for (U64 i = 0; i < KB(1); i++) { - ptr = arena_push(&arena, MB(1) + 3, 8); - MemoryZero(ptr, MB(1)); + for (U64 i = 0; i < MB(4); i++) { + ptr = arena_push(&arena, 3, 1); + MemoryZero(ptr, 3); } arena_free(&arena); } @@ -166,7 +167,7 @@ int main(int argc, char *argv[]) { // arena_test_1(); arena_test_2(); - // arena_test_3(); + arena_test_3(); arena_test_4(); } diff --git a/src/mini_arena.h b/src/mini_arena.h index c844aa1..22428d3 100644 --- a/src/mini_arena.h +++ b/src/mini_arena.h @@ -1,96 +1,94 @@ #pragma once #include "base_core.h" -typedef struct MiniArena MiniArena; -struct MiniArena { - U8 *start; // start of user buffer - U8 *curr; // next alloc point - U8 *end; // one past end of user buffer - int checkpoint_level; // level of miniarenatmp_begin stacks +// Mini Arena for arena allocations from a supplied buffer + +typedef struct MArena MArena; +struct MArena { + U8 *base; // start of buffer + U32 first_free; // next alloc point + U32 size; + S32 checkpoint_level; // level of marenatmp_begin nesting }; -typedef struct MiniArenaCheckpoint MiniArenaCheckpoint; -struct MiniArenaCheckpoint { - U8 *alloc_point; - MiniArena *arena; +typedef struct MArenaCheckpoint MArenaCheckpoint; +struct MArenaCheckpoint { + U32 offset; + MArena *arena; }; -#define LARENA_STATIC_INITIALIZER(data) LARENA_INITIALIZER((data), sizeof(data)) -#define LARENA_INITIALIZER(data, sz) {.start = (data), .curr = (data), .end = (data) + sz, .checkpoint_level = 0} -#define LARENA_DEFINE(var_name, size_, alignment_) \ +#define MARENA_STATIC_INITIALIZER(data) MARENA_INITIALIZER((data), sizeof(data)) +#define MARENA_INITIALIZER(data, size) {.base = (data), .base = (data), .first_free = 0, .size = (U32)sizeof(data), checkpoint_level = 0} +#define MARENA_DEFINE(var_name, size, alignment_) \ struct { \ - _Alignas(alignment_) U8 memory[size_]; \ + _Alignas(alignment_) U8 memory[size]; \ } var_name##_arena_memory; \ - MiniArena var_name = LARENA_STATIC_INITIALIZER(var_name##_arena_memory.memory) -#define LARENA_ALLOC_TYPE(allocator, type_) miniarenaalloc_aligned((allocator), sizeof(type_), _Alignof(type_)) -#define LARENA_ALLOC_ARRAY(allocator, type_, nr_elements_) miniarenaalloc_aligned((allocator), (nr_elements_) * sizeof(type_), _Alignof(type_)) -static INLINE size_t miniarena_size(const MiniArena *arena) + MArena var_name = MARENA_STATIC_INITIALIZER(var_name##_arena_memory.memory) + + + +static INLINE void marena_init(MArena *arena, void *memory, U32 size) { - return (size_t)(arena->end - arena->start); + Assert(memory != NULL); + arena->base = (U8 *)memory; + arena->first_free = 0; + arena->size = size; } -static INLINE size_t miniarena_used(const MiniArena *arena) +static INLINE MArenaCheckpoint marenatmp_begin(MArena *arena) { - return (size_t)(arena->curr - arena->start); -} -static INLINE size_t miniarena_available(const MiniArena *arena) -{ - return miniarena_size(arena) - miniarena_used(arena); -} + MArenaCheckpoint checkpoint = {}; -static INLINE void miniarena_init(MiniArena *arena, void *memory, size_t sz) -{ - arena->start = arena->curr = (U8 *)memory; - arena->end = arena->start + sz; -} - -static INLINE MiniArenaCheckpoint miniarenatmp_begin(MiniArena *arena) -{ - MiniArenaCheckpoint checkpoint = {}; - - checkpoint.arena = arena; - checkpoint.alloc_point = arena->curr; + checkpoint.arena = arena; + checkpoint.offset = arena->first_free; arena->checkpoint_level++; return checkpoint; } -static INLINE void miniarenatmp_end(MiniArenaCheckpoint *state) +static INLINE void marenatmp_end(MArenaCheckpoint *state) { - MiniArena *arena = state->arena; + MArena *arena = state->arena; Assert(arena->checkpoint_level > 0); - arena->curr = state->alloc_point; + arena->first_free = state->offset; arena->checkpoint_level--; } -static INLINE void *miniarena_push(MiniArena *arena, size_t sz) + +#define marena_push_type(allocator, type_) marenaalloc_aligned((allocator), sizeof(type_), _Alignof(type_)) +#define marena_push_array(allocator, type_, nr_elements_) marenaalloc_aligned((allocator), (nr_elements_) * (U32)sizeof(type_), _Alignof(type_)) + + +static INLINE void *marena_push(MArena *arena, U32 size) { - if (sz > miniarena_available(arena)) { + if (size > arena->size - arena->first_free) { return NULL; } - void *start = arena->curr; - arena->curr += sz; - return start; + void *base = &arena->base[arena->first_free]; + arena->first_free += size; + return base; } [[gnu::alloc_align(3)]] -static INLINE void *miniaren_push_aligned(MiniArena *arena, size_t sz, unsigned int align) +static INLINE void *maren_push_aligned(MArena *arena, U32 size, U32 align) { Assert(IsPow2(align)); - uintptr_t curr = (uintptr_t)arena->curr; - uintptr_t aligned = AlignUp(curr, align); - U8 *start = (U8 *)aligned; - - if (sz > (size_t)(arena->end - start)) { + U32 aligned = AlignUp(arena->first_free, align); + if (aligned < arena->first_free) { // align wrapped return NULL; } - arena->curr = start + sz; + if (aligned > arena->size || size > arena->size - aligned) { + return NULL; + } - return start; + void *base = &arena->base[aligned]; + arena->first_free = aligned + size; + + return base; } -static INLINE void miniarena_reset(MiniArena *arena) +static INLINE void marena_reset(MArena *arena) { - arena->curr = arena->start; + arena->first_free = 0; }