summaryrefslogtreecommitdiff
path: root/base/base_arena.c
diff options
context:
space:
mode:
Diffstat (limited to 'base/base_arena.c')
-rw-r--r--base/base_arena.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/base/base_arena.c b/base/base_arena.c
new file mode 100644
index 0000000..16997b2
--- /dev/null
+++ b/base/base_arena.c
@@ -0,0 +1,86 @@
1/**
2 * TODO(nasr): remove stdlib
3 * */
4#include <assert.h>
5#include <stdint.h>
6#include <string.h>
7#include <sys/mman.h>
8#include <sys/stat.h>
9#include <dirent.h>
10#include <fcntl.h>
11#include <unistd.h>
12
13#include "base_arena.h"
14
15/* TODO(nasr): reserve pages support */
16/* TODO(nasr): check if an arena has been used before */
17
18local_internal mem_arena *
19arena_create(u64 capacity)
20{
21 mem_arena *arena = (mem_arena *)mmap(0, capacity, PROT_READ | PROT_WRITE | PROT_EXEC,
22 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
23 if (arena == MAP_FAILED)
24 {
25 return NULL;
26 }
27
28 arena->capacity = capacity;
29 arena->pos = ARENA_BASE_POS;
30
31 return arena;
32}
33
34/*
35 * make it a void pointer to allow implicit conversion
36 * */
37local_internal void
38arena_destroy(mem_arena *arena)
39{
40 munmap(arena, arena->capacity);
41}
42
43local_internal void *
44arena_push(mem_arena *arena, u64 size, b32 non_zero)
45{
46 u64 pos_aligned = ALIGN_UP_POW2(arena->pos, ARENA_ALIGN);
47 u64 new_pos = pos_aligned + size;
48
49 if (new_pos > arena->capacity)
50 {
51 assert(0);
52 return NULL;
53 }
54
55 arena->pos = new_pos;
56 /*
57 * cast to u8 to be able to do pointer arithemtic
58 * */
59 u8 *out = (u8 *)arena + pos_aligned;
60
61 if (!non_zero)
62 {
63 memset(out, 0, size);
64 }
65 return out;
66}
67
68local_internal void
69arena_pop(mem_arena *arena, u64 size)
70{
71 size = MIN(size, arena->pos - ARENA_BASE_POS);
72 arena->pos -= size;
73}
74
75local_internal void
76arena_pop_to(mem_arena *arena, u64 pos)
77{
78 u64 size = pos < arena->pos ? arena->pos - pos : 0;
79 arena_pop(arena, size);
80}
81
82local_internal void
83arena_clear(mem_arena *arena)
84{
85 arena_pop_to(arena, ARENA_BASE_POS);
86}