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; +}