summaryrefslogtreecommitdiff
path: root/source/base/base_arena.cpp
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.cpp
init: base
Diffstat (limited to 'source/base/base_arena.cpp')
-rw-r--r--source/base/base_arena.cpp165
1 files changed, 165 insertions, 0 deletions
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 @@
1#if PLATFORM_UNIX
2
3internal MemArena *
4unix_arena_create(u64 capacity)
5{
6 MemArena *arena = (MemArena *)mmap(
7 /* kernel decides where to throw the arena */
8 NULL,
9 capacity + sizeof(MemArena),
10 PROT_READ | PROT_WRITE,
11 MAP_SHARED | MAP_ANONYMOUS,
12 -1,
13 0);
14
15 if(arena == MAP_FAILED) {
16 return NULL;
17 }
18
19 arena->capacity = capacity;
20 arena->base_position = (u8 *)arena + sizeof(MemArena);
21 arena->current_position = 0;
22 arena->previous_position = 0;
23
24 return arena;
25}
26
27internal void
28unix_arena_destroy(MemArena *arena)
29{
30 if(!arena) {
31 return;
32 }
33
34 munmap(arena, arena->capacity + sizeof(MemArena));
35}
36
37#elif PLATFORM_WINDOWS
38
39internal MemArena *
40win32_arena_create(u64 capacity)
41{
42 MemArena *arena = (MemArena *)VirtualAlloc(NULL,
43 capacity + sizeof(MemArena),
44 MEM_COMMIT | MEM_RESERVE,
45 PAGE_READWRITE);
46 if(!arena) {
47 return NULL;
48 }
49
50 arena->capacity = capacity;
51 arena->base_position = (u8 *)arena + sizeof(MemArena);
52 arena->current_position = 0;
53 arena->previous_position = 0;
54 return arena;
55}
56
57internal void
58win32_arena_destroy(MemArena *arena)
59{
60 if(!arena) {
61 return;
62 }
63
64 VirtualFree(arena, 0, MEM_RELEASE);
65 return;
66}
67
68#endif
69
70internal void *
71arena_alloc(MemArena *arena, u64 size, b32 zero)
72{
73 Assert(arena);
74
75 u64 aligned = Align(arena->current_position, arena_align);
76 u64 new_pos = aligned + size;
77
78 AssertLog((new_pos <= arena->capacity), "max arena capacity reached\n");
79
80
81 void *out = arena->base_position + aligned;
82
83 arena->previous_position = arena->current_position;
84 arena->current_position = aligned + size;
85
86 if(zero) {
87 MemSetZero(out, size);
88 }
89
90 return out;
91}
92
93internal void
94arena_pop(MemArena *arena, u64 size)
95{
96 size = Min(size, arena->current_position);
97 arena->current_position -= size;
98}
99
100internal void
101arena_pop_to(MemArena *arena, u64 pos)
102{
103 u64 size = pos < arena->current_position ? arena->current_position - pos : 0;
104 arena_pop(arena, size);
105}
106
107internal void
108arena_clear(MemArena *arena)
109{
110 arena->current_position = 0;
111}
112
113internal MemArena *
114arena_resize_block_align(MemArena *arena, void *old_memory, u64 new_size, u64 old_size, umm alignment)
115{
116 u8 *old_mem = (u8 *)old_memory;
117
118 if(is_pow(alignment)) {
119 arena->current_position = Align(arena->current_position, alignment);
120 }
121
122 if(old_memory == NULL || old_size == 0) {
123 return (MemArena *)arena_alloc(arena, new_size, 0);
124 } 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
125 if((arena->base_position + arena->previous_position) == old_memory) {
126 arena->current_position = arena->previous_position + new_size;
127 if(new_size > old_size) {
128 MemSet(&arena->current_position, new_size - old_size);
129 }
130
131 return (MemArena *)old_memory;
132 } else {
133 void *new_memory = arena_alloc(arena, new_size, 0);
134 umm copy_size = old_size < new_size ? old_size : new_size;
135 memmove(new_memory, old_mem, copy_size);
136 }
137 } else {
138 AssertLog(false, "Failed to resize memory.\n");
139 }
140
141 return NULL;
142}
143
144internal MemArena *
145arena_resize_block(MemArena *arena, void *old_memory, u64 new_size, u64 old_size)
146{
147 return arena_resize_block_align(arena, old_memory, new_size, old_size, arena_align);
148}
149
150internal ScratchArena
151scratch_start(MemArena *arena)
152{
153 ScratchArena scratch;
154 scratch.arena = arena;
155 scratch.start_position = arena->current_position;
156
157 return scratch;
158}
159
160internal void
161scratch_end(ScratchArena *scratch)
162{
163 scratch->arena->current_position = scratch->start_position;
164}
165