arena allocators are fully implemented
This commit is contained in:
+5
-5
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 //////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user