diff options
-rw-r--r-- | README.md | 17 | ||||
-rw-r--r-- | arena.c | 56 | ||||
-rw-r--r-- | arena.h | 15 |
3 files changed, 88 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..ac03e6f --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# arena +Minimal arena allocator for C. + +## Installation +The **arena.c** and **arena.h** files can be dropped into an existing C project +and compiled it along it. + +## Usage +- `arena_t* arena_create_sized(size_t size);`: Create an arena with size `size` + +- `arena_t* arena_create(void);`: Create an arena with a compile-time specified + page size (4096 by default) + +- `void* arena_malloc(arena_t* arena, size_t size);`: Allocate `size` bytes inside + the arena + +- `void arena_destroy(arena_t* arena);`: Destroy the arena diff --git a/arena.c b/arena.c new file mode 100644 index 0000000..3e1a57c --- /dev/null +++ b/arena.c @@ -0,0 +1,56 @@ +#include "arena.h" +#include <stdlib.h> +#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; +} diff --git a/arena.h b/arena.h new file mode 100644 index 0000000..4594070 --- /dev/null +++ b/arena.h @@ -0,0 +1,15 @@ +#ifndef ARENA_H +#define ARENA_H +#include <stdint.h> +#include <stddef.h> +typedef struct arena { + uint8_t* memory; + size_t size; + size_t fill; + struct arena* next; +} arena_t; +arena_t* arena_create_sized(size_t size); +arena_t* arena_create(void); +void* arena_malloc(arena_t* arena, size_t size); +void arena_destroy(arena_t* arena); +#endif |