From a307f17f44b461f58441926fcbf87883f17ebe61 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 24 Feb 2019 17:53:46 +0100 Subject: Fixed CHECK_RESULT macro, use scoped allocator Scoped allocator gives us better performance and cleanup code for error cases is much cleaner --- src/scoped_allocator.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/scoped_allocator.c (limited to 'src/scoped_allocator.c') diff --git a/src/scoped_allocator.c b/src/scoped_allocator.c new file mode 100644 index 0000000..ea99774 --- /dev/null +++ b/src/scoped_allocator.c @@ -0,0 +1,60 @@ +#include "../include/scoped_allocator.h" +#include "../include/alloc.h" +#include + +#define ALLOC_NODE_SIZE 4096 + +int scoped_allocator_node_init(ScopedAllocatorNode *self) { + self->data = NULL; + self->size = 0; + self->next = NULL; + return am_malloc(ALLOC_NODE_SIZE, (void**)&self->data); +} + +void scoped_allocator_node_deinit(ScopedAllocatorNode *self) { + am_free(self->data); + self->data = NULL; + self->size = 0; + if(self->next) { + scoped_allocator_node_deinit(self->next); + am_free(self->next); + self->next = NULL; + } +} + +int scoped_allocator_init(ScopedAllocator *self) { + return_if_error(scoped_allocator_node_init(&self->head)); + self->current = &self->head; + return 0; +} +void scoped_allocator_deinit(ScopedAllocator *self) { + scoped_allocator_node_deinit(&self->head); + self->current = NULL; +} + +static CHECK_RESULT int scoped_allocator_ensure_capacity_for(ScopedAllocator *self, usize size) { + void *new_node; + new_node = NULL; + + if(self->current->size + size > ALLOC_NODE_SIZE) { + return_if_error(am_malloc(sizeof(ScopedAllocatorNode), &new_node)); + cleanup_if_error(scoped_allocator_node_init(new_node)); + self->current->next = new_node; + self->current = new_node; + } + return 0; + + cleanup: + if(new_node) + am_free(new_node); + return -1; +} + +int scoped_allocator_alloc(ScopedAllocator *self, usize size, void **mem) { + assert(self->current); + assert(size <= ALLOC_NODE_SIZE); + return_if_error(scoped_allocator_ensure_capacity_for(self, size)); + *mem = &self->current->data[self->current->size]; + self->current->size += size; + return 0; +} \ No newline at end of file -- cgit v1.2.3