aboutsummaryrefslogtreecommitdiff
path: root/v1/arena.h
diff options
context:
space:
mode:
Diffstat (limited to 'v1/arena.h')
-rw-r--r--v1/arena.h116
1 files changed, 116 insertions, 0 deletions
diff --git a/v1/arena.h b/v1/arena.h
new file mode 100644
index 0000000..6f371f4
--- /dev/null
+++ b/v1/arena.h
@@ -0,0 +1,116 @@
+#ifndef ARENA_IMPL
+#define ARENA_IMPL
+
+#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
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+typedef int8_t s8;
+typedef int16_t s16;
+typedef int32_t s32;
+typedef int64_t s64;
+
+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)
+{
+ u64 *mem;
+ mem = (u64 *)arena->memory + arena->pos;
+ arena->pos += size;
+ return mem;
+}
+
+void *ArenaPushZero(Arena *arena, u64 size)
+{
+ u64 *mem;
+ mem = (u64 *)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