Update mini arena

This commit is contained in:
Nils O. Selåsdal
2026-06-10 16:43:22 +02:00
parent 99bcba9c4c
commit ba471f41b7
2 changed files with 60 additions and 61 deletions
+6 -5
View File
@@ -1,5 +1,6 @@
#include "base_core.h" #include "base_core.h"
#include "arena.h" #include "arena.h"
#include "mini_arena.h"
#include "platform.h" #include "platform.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -91,12 +92,12 @@ static void arena_test_2(void)
((U8*)ptr)[0] = 0x73; ((U8*)ptr)[0] = 0x73;
ptr = arena_push(&arena, 0, KB(4)); ptr = arena_push(&arena, 0, KB(4));
//((U8*)ptr)[0] = 0x73; //((U8*)ptr)[0] = 0x73;
arena_reset_to(&arena, 1089); // arena_reset_to(&arena, 1089);
arena_dump(&arena); arena_dump(&arena);
arena_reset_to(&arena, 0); arena_reset_to(&arena, 0);
for (U64 i = 0; i < KB(1); i++) { for (U64 i = 0; i < MB(4); i++) {
ptr = arena_push(&arena, MB(1) + 3, 8); ptr = arena_push(&arena, 3, 1);
MemoryZero(ptr, MB(1)); MemoryZero(ptr, 3);
} }
arena_free(&arena); arena_free(&arena);
} }
@@ -166,7 +167,7 @@ int main(int argc, char *argv[])
{ {
// arena_test_1(); // arena_test_1();
arena_test_2(); arena_test_2();
// arena_test_3(); arena_test_3();
arena_test_4(); arena_test_4();
} }
+53 -55
View File
@@ -1,96 +1,94 @@
#pragma once #pragma once
#include "base_core.h" #include "base_core.h"
typedef struct MiniArena MiniArena; // Mini Arena for arena allocations from a supplied buffer
struct MiniArena {
U8 *start; // start of user buffer typedef struct MArena MArena;
U8 *curr; // next alloc point struct MArena {
U8 *end; // one past end of user buffer U8 *base; // start of buffer
int checkpoint_level; // level of miniarenatmp_begin stacks U32 first_free; // next alloc point
U32 size;
S32 checkpoint_level; // level of marenatmp_begin nesting
}; };
typedef struct MiniArenaCheckpoint MiniArenaCheckpoint; typedef struct MArenaCheckpoint MArenaCheckpoint;
struct MiniArenaCheckpoint { struct MArenaCheckpoint {
U8 *alloc_point; U32 offset;
MiniArena *arena; MArena *arena;
}; };
#define LARENA_STATIC_INITIALIZER(data) LARENA_INITIALIZER((data), sizeof(data)) #define MARENA_STATIC_INITIALIZER(data) MARENA_INITIALIZER((data), sizeof(data))
#define LARENA_INITIALIZER(data, sz) {.start = (data), .curr = (data), .end = (data) + sz, .checkpoint_level = 0} #define MARENA_INITIALIZER(data, size) {.base = (data), .base = (data), .first_free = 0, .size = (U32)sizeof(data), checkpoint_level = 0}
#define LARENA_DEFINE(var_name, size_, alignment_) \ #define MARENA_DEFINE(var_name, size, alignment_) \
struct { \ struct { \
_Alignas(alignment_) U8 memory[size_]; \ _Alignas(alignment_) U8 memory[size]; \
} var_name##_arena_memory; \ } var_name##_arena_memory; \
MiniArena var_name = LARENA_STATIC_INITIALIZER(var_name##_arena_memory.memory) MArena var_name = MARENA_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)
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); MArenaCheckpoint checkpoint = {};
}
static INLINE size_t miniarena_available(const MiniArena *arena)
{
return miniarena_size(arena) - miniarena_used(arena);
}
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.arena = arena;
checkpoint.alloc_point = arena->curr; checkpoint.offset = arena->first_free;
arena->checkpoint_level++; arena->checkpoint_level++;
return checkpoint; 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); Assert(arena->checkpoint_level > 0);
arena->curr = state->alloc_point; arena->first_free = state->offset;
arena->checkpoint_level--; 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; return NULL;
} }
void *start = arena->curr; void *base = &arena->base[arena->first_free];
arena->curr += sz; arena->first_free += size;
return start; return base;
} }
[[gnu::alloc_align(3)]] [[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)); Assert(IsPow2(align));
uintptr_t curr = (uintptr_t)arena->curr; U32 aligned = AlignUp(arena->first_free, align);
uintptr_t aligned = AlignUp(curr, align); if (aligned < arena->first_free) { // align wrapped
U8 *start = (U8 *)aligned;
if (sz > (size_t)(arena->end - start)) {
return NULL; 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;
} }