wizapp-stdlib/mem/src/arena/mem_arena.c

90 lines
2.0 KiB
C

#include "mem_arena.h"
#include "aliases.h"
#include "mem_utils.h"
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#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) {
if (!arena || arena->buf) {
return false;
}
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) {
if (!arena) {
return NULL;
}
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) {
if (!arena) {
return;
}
memset(arena->buf, 0, arena->offset - arena->buf);
arena->offset = arena->buf;
}
internal void base_arena_free(BaseArena *arena) {
if (!arena) {
return;
}
if (arena->buf) {
free(arena->buf);
}
arena->buf = arena->offset = NULL;
arena->capacity = 0;
arena->prev = arena->next = NULL;
}