#include "arena.h" #include #define PAGE_SIZE 4096 enum { ARENA_SUCCESS = 0, ARENA_EXPAND, ARENA_FAILURE, } int arena_errno; arena_t* arena_create_sized(size_t size){ arena_t* arena = (arena_t*) calloc(1, sizeof(arena_t*)); if (!arena) { arena_errno = ARENA_FAILURE; return 0; } arena->memory = (uint8_t*) calloc(1, size); arena->size = size; if (!arena->memory) { free(arena); arena_errno = ARENA_FAILURE; return 0; } arena_errno = ARENA_SUCCESS; return arena; } arena_t* arena_create() { return arena_create_sized(PAGE_SIZE); } void* arena_malloc(arena_t* arena, size_t size) { arena_t* head = arena; arena_t* tail; do { if ((arena->size - arena->fill) > size) { arena->fill += size; // NOTE: do not overwrite ARENA_EXPAND code if (arena_errno != ARENA_EXPAND) arena_errno = ARENA_SUCCESS; return arena->memory + (arena->fill - size); } } while ((arena = arena->next) != 0); tail = arena_create(); if (tail == 0) { // NOTE: `arena_errno` is already set from `arena_create` return 0; } arena_errno = ARENA_EXPAND; return arena_malloc(tail, size); } void arena_destroy(arena_t* arena) { arena_t* tail = arena; do { free(tail->memory); free(tail); tail = tail->next; } while (tail != 0); arena_errno = ARENA_SUCCESS; }