From 76d85a10f6cda93eba29dad5372e8160af7289c8 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 27 Feb 2019 22:26:35 +0100 Subject: Use multiple threads to parse --- src/std/scoped_allocator.c | 102 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/std/scoped_allocator.c (limited to 'src/std/scoped_allocator.c') diff --git a/src/std/scoped_allocator.c b/src/std/scoped_allocator.c new file mode 100644 index 0000000..d53edad --- /dev/null +++ b/src/std/scoped_allocator.c @@ -0,0 +1,102 @@ +#include "../../include/std/scoped_allocator.h" +#include "../../include/std/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 buffer_init(&self->buffers, NULL); +} + +static void buffer_deinit(Buffer *self) { + am_free(self->data); + self->data = NULL; + self->size = 0; + self->capacity = 0; +} + +void scoped_allocator_deinit(ScopedAllocator *self) { + Buffer *buffer; + Buffer *buffer_end; + + scoped_allocator_node_deinit(&self->head); + self->current = NULL; + buffer = (Buffer*)self->buffers.data; + buffer_end = buffer + self->buffers.size / sizeof(Buffer); + while(buffer != buffer_end) { + buffer_deinit(buffer); + ++buffer; + } + buffer_deinit(&self->buffers); +} + +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 ALLOC_OK; + + cleanup: + if(new_node) + am_free(new_node); + return ALLOC_FAIL; +} + +static void* align_ptr_ceil(void *ptr, uintptr_t alignment) { + uintptr_t ptrval; + ptrval = (uintptr_t)ptr; + return (void*)((ptrval + alignment + 1) & ~(alignment - 1)); +} + +static usize align_ptr_ceil_offset(void *ptr, uintptr_t alignment) { + return (uintptr_t)align_ptr_ceil(ptr, alignment) - (uintptr_t)ptr; +} + +int scoped_allocator_alloc(ScopedAllocator *self, usize size, void **mem) { + ScopedAllocatorNode *current; + usize alloc_size; + assert(self->current); + assert(size <= ALLOC_NODE_SIZE); + current = self->current; + + alloc_size = size + align_ptr_ceil_offset(self->current->data + self->current->size, 16); + return_if_error(scoped_allocator_ensure_capacity_for(self, alloc_size)); + /* Reallocated (new node created) */ + if(self->current != current) { + *mem = self->current->data; + } else { + *mem = align_ptr_ceil(self->current->data + self->current->size, 16); + } + self->current->size = size; + return 0; +} + +int scoped_allocator_add_buffer(ScopedAllocator *self, Buffer *buffer) { + return buffer_append(&self->buffers, buffer, sizeof(Buffer)); +} \ No newline at end of file -- cgit v1.2.3