aboutsummaryrefslogtreecommitdiff
path: root/v2/arena.h
diff options
context:
space:
mode:
authorRaymaekers Luca <raymaekers.luca@gmail.com>2024-10-24 23:14:18 +0200
committerRaymaekers Luca <raymaekers.luca@gmail.com>2024-10-24 23:14:18 +0200
commit66a153c5012f0237bdf67b79b5cc6b2f5f496879 (patch)
treeb59dfad2b36a8cb49fda7d22145ba711d294e894 /v2/arena.h
parentf37cce374cc9da243fc2babbea9a7051f15db80a (diff)
Initial draft for v2
This is a rewrite of v1 using arena's as memory allocators. The other great difference is using wide strings by default (wchar_t) because that will be needed in the future to print pretty UIs.
Diffstat (limited to 'v2/arena.h')
-rw-r--r--v2/arena.h109
1 files changed, 109 insertions, 0 deletions
diff --git a/v2/arena.h b/v2/arena.h
new file mode 100644
index 0000000..9327a5e
--- /dev/null
+++ b/v2/arena.h
@@ -0,0 +1,109 @@
+#ifndef ARENA_IMPL
+#define ARENA_IMPL
+
+#include "common.h"
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#define PAGESIZE 4096
+
+#ifndef ARENA_MEMORY
+#define ARENA_MEMORY PAGESIZE
+#endif
+
+struct Arena {
+ void *memory;
+ u64 size;
+ u64 pos;
+} typedef Arena;
+
+// Create an arena
+Arena *ArenaAlloc(void);
+// Destroy an arena
+void ArenaRelease(Arena *arena);
+
+// Push bytes on to the arena | allocating
+void *ArenaPush(Arena *arena, u64 size);
+void *ArenaPushZero(Arena *arena, u64 size);
+
+#define PushArray(arena, type, count) (type *)ArenaPush((arena), sizeof(type)*(count))
+#define PushArrayZero(arena, type, count) (type *)ArenaPushZero((arena), sizeof(type) * (count))
+#define PushStruct(arena, type) PushArray((arena), (type), 1)
+#define PushStructZero(arena, type) PushArrayZero((arena), (type), 1)
+
+// Free some bytes by popping the stack
+void ArenaPop(Arena *arena, u64 size);
+// Get the number of bytes allocated
+u64 ArenaGetPos(Arena *arena);
+
+void ArenaSetPosBack(Arena *arena, u64 pos);
+void ArenaClear(Arena *arena);
+
+Arena *ArenaAlloc(void)
+{
+ // NOTE: If the arena is created here the pointer to the memory get's overwritten with size in
+ // ArenaPush, so we are forced to use malloc
+ Arena *arena = malloc(sizeof(Arena));
+
+ arena->memory = mmap(NULL, ARENA_MEMORY, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+ if (arena->memory == MAP_FAILED)
+ return NULL;
+
+ arena->pos = 0;
+ arena->size = ARENA_MEMORY;
+
+ return arena;
+}
+
+void ArenaRelease(Arena *arena)
+{
+ munmap(arena->memory, ARENA_MEMORY);
+ free(arena);
+}
+
+void *ArenaPush(Arena *arena, u64 size)
+{
+ u8 *mem;
+ mem = (u8 *)arena->memory + arena->pos;
+ arena->pos += size;
+ return mem;
+}
+
+void *ArenaPushZero(Arena *arena, u64 size)
+{
+ u8 *mem;
+ mem = (u8 *)arena->memory + arena->pos;
+ bzero(mem, size);
+ arena->pos += size;
+ return mem;
+}
+
+void ArenaPop(Arena *arena, u64 size)
+{
+ arena->pos -= size;
+}
+
+u64 ArenaGetPos(Arena *arena)
+{
+ return arena->pos;
+}
+
+void ArenaSetPosBack(Arena *arena, u64 pos)
+{
+ arena->pos -= pos;
+}
+
+void ArenaClear(Arena *arena)
+{
+ bzero(arena->memory, arena->size);
+ arena->pos = 0;
+}
+
+#endif