aboutsummaryrefslogtreecommitdiffstats
path: root/src/arena.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arena.c')
-rw-r--r--src/arena.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/arena.c b/src/arena.c
new file mode 100644
index 0000000..2221616
--- /dev/null
+++ b/src/arena.c
@@ -0,0 +1,50 @@
+#include "arena.h"
+
+struct block {
+ size_t size;
+ size_t used;
+ struct block *next;
+ char data_start[];
+};
+
+static const size_t min_block_room = 16 * 1024 - sizeof(struct block);
+
+static void add_block(struct arena* a, size_t room_wanted)
+{
+ if (room_wanted < min_block_room) {
+ room_wanted = min_block_room;
+ }
+ struct block *new_block = malloc(sizeof(struct block) + room_wanted);
+ new_block->size = room_wanted;
+ new_block->used = 0;
+ new_block->next = a->cur_block;
+ a->cur_block = new_block;
+}
+
+void arena_init(struct arena *a)
+{
+ a->cur_block = NULL;
+}
+
+void* arena_malloc(struct arena *a, size_t amount)
+{
+ struct block* b = a->cur_block;
+ if (b == NULL || b->size - b->used < amount) {
+ add_block(a, amount);
+ b = a->cur_block;
+ }
+ void* result = &b->data_start[b->used];
+ b->used += amount;
+ return result;
+}
+
+void arena_free(struct arena *a)
+{
+ struct block* b = a->cur_block;
+ while (b != NULL) {
+ struct block* next = b->next;
+ free(b);
+ b = next;
+ }
+ a->cur_block = NULL;
+}