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
|