From f6d3090f7fa76eb8e0dbe060b8490cb49c001c39 Mon Sep 17 00:00:00 2001 From: nasr Date: Mon, 5 Oct 2026 22:02:56 +0200 Subject: init: base --- source/base/base_arena.cpp | 165 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 source/base/base_arena.cpp (limited to 'source/base/base_arena.cpp') diff --git a/source/base/base_arena.cpp b/source/base/base_arena.cpp new file mode 100644 index 0000000..b4235e6 --- /dev/null +++ b/source/base/base_arena.cpp @@ -0,0 +1,165 @@ +#if PLATFORM_UNIX + +internal MemArena * +unix_arena_create(u64 capacity) +{ + MemArena *arena = (MemArena *)mmap( + /* kernel decides where to throw the arena */ + NULL, + capacity + sizeof(MemArena), + PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, + -1, + 0); + + if(arena == MAP_FAILED) { + return NULL; + } + + arena->capacity = capacity; + arena->base_position = (u8 *)arena + sizeof(MemArena); + arena->current_position = 0; + arena->previous_position = 0; + + return arena; +} + +internal void +unix_arena_destroy(MemArena *arena) +{ + if(!arena) { + return; + } + + munmap(arena, arena->capacity + sizeof(MemArena)); +} + +#elif PLATFORM_WINDOWS + +internal MemArena * +win32_arena_create(u64 capacity) +{ + MemArena *arena = (MemArena *)VirtualAlloc(NULL, + capacity + sizeof(MemArena), + MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE); + if(!arena) { + return NULL; + } + + arena->capacity = capacity; + arena->base_position = (u8 *)arena + sizeof(MemArena); + arena->current_position = 0; + arena->previous_position = 0; + return arena; +} + +internal void +win32_arena_destroy(MemArena *arena) +{ + if(!arena) { + return; + } + + VirtualFree(arena, 0, MEM_RELEASE); + return; +} + +#endif + +internal void * +arena_alloc(MemArena *arena, u64 size, b32 zero) +{ + Assert(arena); + + u64 aligned = Align(arena->current_position, arena_align); + u64 new_pos = aligned + size; + + AssertLog((new_pos <= arena->capacity), "max arena capacity reached\n"); + + + void *out = arena->base_position + aligned; + + arena->previous_position = arena->current_position; + arena->current_position = aligned + size; + + if(zero) { + MemSetZero(out, size); + } + + return out; +} + +internal void +arena_pop(MemArena *arena, u64 size) +{ + size = Min(size, arena->current_position); + arena->current_position -= size; +} + +internal void +arena_pop_to(MemArena *arena, u64 pos) +{ + u64 size = pos < arena->current_position ? arena->current_position - pos : 0; + arena_pop(arena, size); +} + +internal void +arena_clear(MemArena *arena) +{ + arena->current_position = 0; +} + +internal MemArena * +arena_resize_block_align(MemArena *arena, void *old_memory, u64 new_size, u64 old_size, umm alignment) +{ + u8 *old_mem = (u8 *)old_memory; + + if(is_pow(alignment)) { + arena->current_position = Align(arena->current_position, alignment); + } + + if(old_memory == NULL || old_size == 0) { + return (MemArena *)arena_alloc(arena, new_size, 0); + } else if((old_mem >= arena->base_position && old_mem < arena->base_position + arena->current_position)) { // NOTE: does not find it self after the current position + if((arena->base_position + arena->previous_position) == old_memory) { + arena->current_position = arena->previous_position + new_size; + if(new_size > old_size) { + MemSet(&arena->current_position, new_size - old_size); + } + + return (MemArena *)old_memory; + } else { + void *new_memory = arena_alloc(arena, new_size, 0); + umm copy_size = old_size < new_size ? old_size : new_size; + memmove(new_memory, old_mem, copy_size); + } + } else { + AssertLog(false, "Failed to resize memory.\n"); + } + + return NULL; +} + +internal MemArena * +arena_resize_block(MemArena *arena, void *old_memory, u64 new_size, u64 old_size) +{ + return arena_resize_block_align(arena, old_memory, new_size, old_size, arena_align); +} + +internal ScratchArena +scratch_start(MemArena *arena) +{ + ScratchArena scratch; + scratch.arena = arena; + scratch.start_position = arena->current_position; + + return scratch; +} + +internal void +scratch_end(ScratchArena *scratch) +{ + scratch->arena->current_position = scratch->start_position; +} + -- cgit v1.3.1