From 633632105b7659ae5d9c53db9757d30768e99939 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sat, 24 Feb 2024 18:40:25 +0000 Subject: [PATCH] Implement base arena allocator --- mem/include/arena/mem_arena.h | 7 ++++ mem/src/arena/mem_arena.c | 73 +++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 mem/include/arena/mem_arena.h create mode 100644 mem/src/arena/mem_arena.c diff --git a/mem/include/arena/mem_arena.h b/mem/include/arena/mem_arena.h new file mode 100644 index 0000000..2ab423c --- /dev/null +++ b/mem/include/arena/mem_arena.h @@ -0,0 +1,7 @@ +#ifndef MEM_ARENA_H +#define MEM_ARENA_H + +#include "aliases.h" +#include + +#endif // !MEM_ARENA_H diff --git a/mem/src/arena/mem_arena.c b/mem/src/arena/mem_arena.c new file mode 100644 index 0000000..729b0aa --- /dev/null +++ b/mem/src/arena/mem_arena.c @@ -0,0 +1,73 @@ +#include "mem_arena.h" +#include "aliases.h" +#include "mem_utils.h" +#include +#include +#include + +#ifndef DEFAULT_ALIGNMENT +#define DEFAULT_ALIGNMENT (2 * sizeof(void *)) +#endif /* ifndef DEFAULT_ALIGNMENT */ + +typedef struct base_arena BaseArena; +struct base_arena { + u8 *buf; + u8 *offset; + u64 capacity; + BaseArena *prev; + BaseArena *next; +}; + +internal bool base_arena_init(BaseArena *arena, u64 capacity); +internal void *base_arena_alloc(BaseArena *arena, u64 size); +internal void *base_arena_alloc_aligned(BaseArena *arena, u64 size, + u64 alignment); +internal void base_arena_clear(BaseArena *arena); +internal void base_arena_free(BaseArena *arena); + +internal bool base_arena_init(BaseArena *arena, u64 capacity) { + u64 alloc_size = sizeof(u8) * capacity; + + arena->buf = (u8 *)malloc(alloc_size); + if (!(arena->buf)) { + return false; + } + + memset(arena->buf, 0, alloc_size); + arena->capacity = capacity; + arena->offset = arena->buf; + arena->prev = arena->next = NULL; + + return true; +} + +internal void *base_arena_alloc(BaseArena *arena, u64 size) { + return base_arena_alloc_aligned(arena, size, DEFAULT_ALIGNMENT); +} + +internal void *base_arena_alloc_aligned(BaseArena *arena, u64 size, + u64 alignment) { + u8 *output = mem_util_align_forward((void *)(arena->offset), alignment); + if (output + size >= arena->buf + arena->capacity) { + return NULL; + } + + arena->offset += size; + + return (void *)output; +} + +internal void base_arena_clear(BaseArena *arena) { + memset(arena->buf, 0, arena->offset - arena->buf); + arena->offset = arena->buf; +} + +internal void base_arena_free(BaseArena *arena) { + if (arena->buf) { + free(arena->buf); + } + + arena->buf = arena->offset = NULL; + arena->capacity = 0; + arena->prev = arena->next = NULL; +}