summaryrefslogtreecommitdiff
path: root/source/base/base_arena.h
diff options
context:
space:
mode:
authornasr <nsrddyn@gmail.com>2026-10-05 22:02:56 +0200
committernasr <nsrddyn@gmail.com>2026-10-05 22:02:56 +0200
commitf6d3090f7fa76eb8e0dbe060b8490cb49c001c39 (patch)
tree433c773997e51f22738acb8b04c4fd2fc6b1bdc9 /source/base/base_arena.h
init: base
Diffstat (limited to 'source/base/base_arena.h')
-rw-r--r--source/base/base_arena.h94
1 files changed, 94 insertions, 0 deletions
diff --git a/source/base/base_arena.h b/source/base/base_arena.h
new file mode 100644
index 0000000..125d043
--- /dev/null
+++ b/source/base/base_arena.h
@@ -0,0 +1,94 @@
1#ifndef BASE_ARENA_H
2#define BASE_ARENA_H
3
4//- arena
5typedef struct MemArena MemArena;
6typedef struct ScratchArena ScratchArena;
7
8// NOTE: used capacity can be calculated so we don't care
9struct MemArena {
10 u64 current_position;
11 u64 previous_position;
12 u64 capacity;
13 u8 *base_position;
14 MemArena *next;
15};
16
17struct ScratchArena {
18 MemArena *arena;
19 u64 start_position;
20};
21
22//-
23
24#if defined(PLATFORM_UNIX)
25
26internal MemArena *unix_arena_create(u64 capacity);
27internal void unix_arena_destroy(MemArena *arena);
28
29#define ArenaCreate(capacity) unix_arena_create(capacity)
30#define ArenaDestroy(arena) unix_arena_destroy(arena)
31#elif defined(PLATFORM_WINDOWS)
32
33internal void win32_arena_destroy(MemArena *arena);
34internal MemArena *win32_arena_create(u64 capacity);
35
36#define ArenaCreate(capacity) win32_arena_create(capacity)
37#define ArenaDestroy(arena) win32_arena_destroy(arena)
38#endif
39
40internal void *arena_alloc(MemArena *arena, u64 size, b32 zero);
41internal void arena_pop(MemArena *arena, u64 size);
42internal void arena_pop_to(MemArena *arena, u64 pos);
43internal void arena_clear(MemArena *arena);
44internal ScratchArena scratch_start(MemArena *arena);
45internal void scratch_end(ScratchArena *scratch);
46internal MemArena *arena_resize_block_align(MemArena *arena, void *old_memory, u64 new_size, u64 old_size,
47 umm alignment);
48internal MemArena *arena_resize_block(MemArena *arena, void *old_memory, u64 new_size, u64 old_size);
49internal u64 arena_calculate_used_capacity(MemArena *arena);
50
51#define Align(pointer, alignment) align((u64)(pointer), (umm)(alignment))
52#define PushStruct(arena, type) (type *)arena_alloc((arena), sizeof(type), 0)
53#define PushStructZero(arena, type) (type *)arena_alloc((arena), sizeof(type), 1)
54#define PushArray(arena, type, len) (type *)arena_alloc((arena), sizeof(type) * (len), 0)
55#define PushArrayZero(arena, type, len) (type *)arena_alloc((arena), sizeof(type) * (len), 1)
56#define ArenaResize(arena, old_memory, new_size, old_size) arena_resize_block(arena, old_memory, new_size, old_size) // takes the address of the allocated block in the arena and grows it with a new size
57#define ArenaPopLastPush(arena) arena_pop_to(arena, arena->previous_position)
58
59
60// claude magic HAHHAHAHAH
61#define LogArena(arena_expr) \
62 do { \
63 MemArena *_a = (arena_expr); \
64 if (!_a) { \
65 Log("[arena] %s = NULL (%s:%d)\n", #arena_expr, __FILE__, __LINE__); \
66 break; \
67 } \
68 unsigned long long _cap = (unsigned long long)_a->capacity; \
69 unsigned long long _cur = (unsigned long long)_a->current_position; \
70 unsigned long long _prev = (unsigned long long)_a->previous_position; \
71 unsigned long long _free = _cur <= _cap ? _cap - _cur : 0; \
72 unsigned long long _last = _cur >= _prev ? _cur - _prev : 0; \
73 double _pct = _cap ? (100.0 * (double)_cur / (double)_cap) : 0.0; \
74 u8 *_expected_base = (u8 *)_a + sizeof(MemArena); \
75 Log("[arena] %s @ %p (%s:%d)\n" \
76 " base_position : %p .. %p%s\n" \
77 " capacity : %llu bytes\n" \
78 " current_position : %llu (used %.2f%%)\n" \
79 " previous_position : %llu\n" \
80 " last alloc size : %llu bytes (current - previous)\n" \
81 " free : %llu bytes (capacity - current)\n" \
82 " next write addr : %p\n", \
83 #arena_expr, (void *)_a, __FILE__, __LINE__, \
84 (void *)_a->base_position, (void *)(_a->base_position + _cap), \
85 _a->base_position == _expected_base ? "" : " <-- base != arena + sizeof(MemArena)", \
86 _cap, _cur, _pct, _prev, _last, _free, \
87 (void *)(_a->base_position + _cur)); \
88 if (_cur > _cap) \
89 Log(" !! OVERFLOW: current_position exceeds capacity by %llu bytes\n", _cur - _cap); \
90 if (_prev > _cur) \
91 Log(" !! previous_position (%llu) > current_position (%llu)\n", _prev, _cur); \
92 } while (0)
93
94#endif /* BASE_ARENA_H */