arena allocators are fully implemented

This commit is contained in:
2025-12-06 14:19:53 +01:00
parent b912759050
commit d6ad1c7602
5 changed files with 92 additions and 10 deletions
+5 -5
View File
@@ -4,7 +4,7 @@
#include <assert.h> #include <assert.h>
#include <stdbool.h> #include <stdbool.h>
void *borrow_allocator_alloc_func(borrow_allocator_t *this, size_t bytes) { static void *borrow_allocator_alloc_func(borrow_allocator_t *this, size_t bytes) {
linked_allocation_node_t *node = malloc(sizeof(*this->head) + bytes); linked_allocation_node_t *node = malloc(sizeof(*this->head) + bytes);
if (node == NULL) { return NULL; } if (node == NULL) { return NULL; }
node->prev = NULL; node->prev = NULL;
@@ -17,7 +17,7 @@ void *borrow_allocator_alloc_func(borrow_allocator_t *this, size_t bytes) {
return &node->data; return &node->data;
} }
void *borrow_allocator_resize_func(borrow_allocator_t *this, void *old_ptr, size_t bytes) { static void *borrow_allocator_resize_func(borrow_allocator_t *this, void *old_ptr, size_t bytes) {
linked_allocation_node_t *old_node = PTR_FROM_FIELD_PTR(linked_allocation_node_t, data, old_ptr); linked_allocation_node_t *old_node = PTR_FROM_FIELD_PTR(linked_allocation_node_t, data, old_ptr);
linked_allocation_node_t *new_node = realloc(old_node, sizeof(*old_node) + bytes); linked_allocation_node_t *new_node = realloc(old_node, sizeof(*old_node) + bytes);
if (new_node == NULL) { return NULL; } if (new_node == NULL) { return NULL; }
@@ -31,7 +31,7 @@ void *borrow_allocator_resize_func(borrow_allocator_t *this, void *old_ptr, size
} }
// TODO: remove // TODO: remove
void borrow_allocator_free(borrow_allocator_t *this, void *old_ptr) { static void borrow_allocator_free(borrow_allocator_t *this, void *old_ptr) {
linked_allocation_node_t *node = PTR_FROM_FIELD_PTR(linked_allocation_node_t, data, old_ptr); linked_allocation_node_t *node = PTR_FROM_FIELD_PTR(linked_allocation_node_t, data, old_ptr);
if (node->prev != NULL) { node->prev->next = node->next; } if (node->prev != NULL) { node->prev->next = node->next; }
if (node->next != NULL) { node->next->prev = node->prev; } if (node->next != NULL) { node->next->prev = node->prev; }
@@ -43,7 +43,7 @@ void borrow_allocator_free(borrow_allocator_t *this, void *old_ptr) {
free(node); free(node);
} }
void borrow_allocator_free_all(borrow_allocator_t *this) { static void borrow_allocator_free_all(borrow_allocator_t *this) {
if (this->head == NULL) { if (this->head == NULL) {
return; return;
} }
@@ -57,7 +57,7 @@ void borrow_allocator_free_all(borrow_allocator_t *this) {
this->head = NULL; this->head = NULL;
} }
size_t borrow_allocator_count_allocations(borrow_allocator_t *this) { static size_t borrow_allocator_count_allocations(borrow_allocator_t *this) {
size_t output = 0; size_t output = 0;
for (linked_allocation_node_t *node = this->head; node != NULL; node = node->next) { for (linked_allocation_node_t *node = this->head; node != NULL; node = node->next) {
output++; output++;
+3 -3
View File
@@ -1,6 +1,6 @@
#include "cig.h" #include "cig.h"
void *buffer_allocator_alloc(buffer_allocator_t *this, size_t bytes) { static void *buffer_allocator_alloc(buffer_allocator_t *this, size_t bytes) {
size_t address_of_new_data = (size_t) &this->data[this->size]; size_t address_of_new_data = (size_t) &this->data[this->size];
size_t offset = address_of_new_data % MAX_ALIGN; size_t offset = address_of_new_data % MAX_ALIGN;
size_t new_size = this->size + offset + bytes; size_t new_size = this->size + offset + bytes;
@@ -13,7 +13,7 @@ void *buffer_allocator_alloc(buffer_allocator_t *this, size_t bytes) {
return ptr; return ptr;
} }
void *buffer_allocator_resize(buffer_allocator_t *this, void *old_ptr, size_t bytes) { static void *buffer_allocator_resize(buffer_allocator_t *this, void *old_ptr, size_t bytes) {
void *new_ptr = buffer_allocator_alloc(this, bytes); void *new_ptr = buffer_allocator_alloc(this, bytes);
if (new_ptr == NULL) { if (new_ptr == NULL) {
return NULL; return NULL;
@@ -26,7 +26,7 @@ void *buffer_allocator_resize(buffer_allocator_t *this, void *old_ptr, size_t by
return new_ptr; return new_ptr;
} }
void buffer_allocator_reset(buffer_allocator_t *this) { static void buffer_allocator_reset(buffer_allocator_t *this) {
this->size = 0; this->size = 0;
} }
+4 -2
View File
@@ -92,14 +92,16 @@ typedef struct arena_allocator {
uint8_t *data; uint8_t *data;
} arena_allocator_t; } arena_allocator_t;
#define arena_allocator_value(INITIAL_CAPACITY) ((arena_allocator_t) { \ #define arena_allocator_value(BACKING_ALLOCATOR, INITIAL_CAPACITY) ((arena_allocator_t) { \
.allocator=borrow_allocator_create(), \ .allocator=BACKING_ALLOCATOR, \
.size=0, \ .size=0, \
.capacity=INITIAL_CAPACITY, \ .capacity=INITIAL_CAPACITY, \
.data=NULL \ .data=NULL \
}) })
allocator_t allocator_from_arena(arena_allocator_t *this); allocator_t allocator_from_arena(arena_allocator_t *this);
#define arena_allocator_create(BACKING_ALLOCATOR, INITIAL_CAPACITY) \
allocator_from_arena(&arena_allocator_value(BACKING_ALLOCATOR, INITIAL_CAPACITY))
// dynamic arrays ////////////////////////////////////////////////////////////// // dynamic arrays //////////////////////////////////////////////////////////////
+79
View File
@@ -0,0 +1,79 @@
#include <criterion/criterion.h>
#include <criterion/internal/assert.h>
#include "cig.h"
Test(arena_allocator, test) {
with_borrow(backing) {
allocator_t arena = arena_allocator_create(backing, 4 * MB);
for ( size_t i = 0; i < 1000; i++ ) {
allocator_reset(arena);
allocator_alloc(arena, 4 * MB);
}
borrow_allocator_t *concrete = (borrow_allocator_t*)backing.this;
size_t n_allocations = 0;
for (linked_allocation_node_t *node = concrete->head; node != NULL; node = node->next) {
n_allocations++;
}
cr_assert_eq(n_allocations, 1);
}
with_borrow(backing) {
allocator_t arena = arena_allocator_create(backing, 0);
for ( size_t i = 0; i < 1000; i++ ) {
allocator_reset(arena);
allocator_alloc(arena, 1 * MB);
allocator_alloc(arena, 1 * MB);
allocator_alloc(arena, 1 * MB);
allocator_alloc(arena, 1 * MB);
}
borrow_allocator_t *concrete = (borrow_allocator_t*)backing.this;
size_t n_allocations = 0;
for (linked_allocation_node_t *node = concrete->head; node != NULL; node = node->next) {
n_allocations++;
}
cr_assert_eq(n_allocations, 1);
}
with_borrow(backing) {
allocator_t arena = arena_allocator_create(backing, 0);
for ( size_t i = 0; i < 1000; i++ ) {
allocator_reset(arena);
allocator_alloc(arena, 1 * MB);
allocator_alloc(arena, 1 * MB);
allocator_alloc(arena, 1 * MB);
allocator_alloc(arena, 1 * MB);
}
borrow_allocator_t *concrete_borrow = (borrow_allocator_t*)backing.this;
arena_allocator_t *concrete_arena = (arena_allocator_t*)arena.this;
size_t n_allocations = 0;
for (linked_allocation_node_t *node = concrete_borrow->head; node != NULL; node = node->next) {
n_allocations++;
}
cr_assert_eq(n_allocations, 1);
cr_assert_eq(concrete_arena->capacity, 4 * MB);
}
with_borrow(backing) {
allocator_t arena = arena_allocator_create(backing, 0);
for ( size_t i = 0; i < 1000; i++ ) {
allocator_reset(arena);
allocator_alloc(arena, 1);
allocator_alloc(arena, 1);
allocator_alloc(arena, 1);
allocator_alloc(arena, 1);
}
borrow_allocator_t *concrete_borrow = (borrow_allocator_t*)backing.this;
arena_allocator_t *concrete_arena = (arena_allocator_t*)arena.this;
size_t n_allocations = 0;
for (linked_allocation_node_t *node = concrete_borrow->head; node != NULL; node = node->next) {
n_allocations++;
}
cr_assert_eq(n_allocations, 1);
const size_t expected_capacity = 4 * MAX_ALIGN;
cr_assert_eq(concrete_arena->capacity, expected_capacity);
}
}
+1
View File
@@ -9,4 +9,5 @@ Test(std_allocator, test) {
void *new_ptr = allocator_resize(this, ptr, 1024*1024*500); void *new_ptr = allocator_resize(this, ptr, 1024*1024*500);
cr_assert(new_ptr != ((void *)0), "non null from realloc"); cr_assert(new_ptr != ((void *)0), "non null from realloc");
cr_assert(new_ptr != ptr, "realloc is not the same ptr as malloc"); cr_assert(new_ptr != ptr, "realloc is not the same ptr as malloc");
free(new_ptr);
} }