From 1f28c3c733ea3ae4234bff91e1c55e61b1ee3e96 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 31 Jul 2019 01:25:05 +0200 Subject: Starting on asm, implementing extern function call so progress is visible --- src/std/arena_allocator.c | 110 +++++++++++++++++++++++++++++++++++++++++++++ src/std/buffer.c | 6 +-- src/std/hash_map.c | 6 +-- src/std/mem.c | 6 +++ src/std/scoped_allocator.c | 110 --------------------------------------------- 5 files changed, 122 insertions(+), 116 deletions(-) create mode 100644 src/std/arena_allocator.c delete mode 100644 src/std/scoped_allocator.c (limited to 'src/std') diff --git a/src/std/arena_allocator.c b/src/std/arena_allocator.c new file mode 100644 index 0000000..20f0394 --- /dev/null +++ b/src/std/arena_allocator.c @@ -0,0 +1,110 @@ +#include "../../include/std/arena_allocator.h" +#include "../../include/std/alloc.h" +#include "../../include/std/thread.h" +#include "../../include/std/log.h" +#include + +#define ALLOC_NODE_SIZE 4096 + +int arena_allocator_node_init(ArenaAllocatorNode *self) { + self->data = NULL; + self->size = 0; + self->next = NULL; + return am_malloc(ALLOC_NODE_SIZE, (void**)&self->data); +} + +void arena_allocator_node_deinit(ArenaAllocatorNode *self) { + am_free(self->data); + self->data = NULL; + self->size = 0; + if(self->next) { + arena_allocator_node_deinit(self->next); + am_free(self->next); + self->next = NULL; + } +} + +int arena_allocator_init(ArenaAllocator *self) { + return_if_error(arena_allocator_node_init(&self->head)); + self->current = &self->head; + return buffer_init(&self->mems, NULL); +} + +static void arena_allocator_deinit_buffers(ArenaAllocator *self) { + void **mem; + void **mems_end; + mem = buffer_begin(&self->mems); + mems_end = buffer_end(&self->mems); + while(mem != mems_end) { + am_free(*mem); + ++mem; + } + buffer_deinit(&self->mems); +} + +void arena_allocator_deinit(ArenaAllocator *self) { + self->current = NULL; + arena_allocator_deinit_buffers(self); + arena_allocator_node_deinit(&self->head); +} + +static CHECK_RESULT int arena_allocator_ensure_capacity_for(ArenaAllocator *self, usize size) { + void *new_node; + new_node = NULL; + + if(self->current->size + size > ALLOC_NODE_SIZE) { + return_if_error(am_malloc(sizeof(ArenaAllocatorNode), &new_node)); + cleanup_if_error(arena_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; +} + +#define SCOPED_ALLOC_ALIGNMENT 8 + +int arena_allocator_alloc(ArenaAllocator *self, usize size, void **mem) { + ArenaAllocatorNode *current; + usize alloc_size; + assert(self->current); + current = self->current; + + if(size >= ALLOC_NODE_SIZE) { + amal_log_error("arena_allocator_alloc: tried to alloc memory of size %lu. Max allowed alloc size is %lu", size, ALLOC_NODE_SIZE); + return -1; + } + + alloc_size = size + align_ptr_ceil_offset(self->current->data + self->current->size, SCOPED_ALLOC_ALIGNMENT); + return_if_error(arena_allocator_ensure_capacity_for(self, alloc_size)); + /* Reallocated (new node created) */ + if(self->current != current) { + *mem = self->current->data; + self->current->size += size; + } else { + *mem = align_ptr_ceil(self->current->data + self->current->size, SCOPED_ALLOC_ALIGNMENT); + self->current->size += alloc_size; + } + return 0; +} + +int arena_allocator_add_mem(ArenaAllocator *self, usize *result_index) { + void *null_data; + null_data = NULL; + *result_index = buffer_get_size(&self->mems, sizeof(void*)); + return buffer_append(&self->mems, &null_data, sizeof(void*)); +} diff --git a/src/std/buffer.c b/src/std/buffer.c index f4e93e5..0e4ca89 100644 --- a/src/std/buffer.c +++ b/src/std/buffer.c @@ -1,16 +1,16 @@ #include "../../include/std/buffer.h" #include "../../include/std/alloc.h" #include "../../include/std/mem.h" -#include "../../include/std/scoped_allocator.h" +#include "../../include/std/arena_allocator.h" #include -int buffer_init(Buffer *self, struct ScopedAllocator *allocator) { +int buffer_init(Buffer *self, struct ArenaAllocator *allocator) { self->data = NULL; self->size = 0; self->capacity = 0; self->allocator = allocator; if(allocator) { - return scoped_allocator_add_mem(allocator, &self->allocator_index); + return arena_allocator_add_mem(allocator, &self->allocator_index); } else { self->allocator_index = ~(usize)0; return 0; diff --git a/src/std/hash_map.c b/src/std/hash_map.c index 1ad0dea..bcb43eb 100644 --- a/src/std/hash_map.c +++ b/src/std/hash_map.c @@ -1,5 +1,5 @@ #include "../../include/std/hash_map.h" -#include "../../include/std/scoped_allocator.h" +#include "../../include/std/arena_allocator.h" #include "../../include/std/mem.h" #include @@ -73,7 +73,7 @@ static void* bucket_node_get_value(HashMapBucketNode *self) { return value; } -int hash_map_init(HashMap *self, ScopedAllocator *allocator, usize value_type_size, +int hash_map_init(HashMap *self, ArenaAllocator *allocator, usize value_type_size, HashMapCompare compare_func, HashMapHash hash_func) { assert(compare_func); assert(hash_func); @@ -91,7 +91,7 @@ int hash_map_init(HashMap *self, ScopedAllocator *allocator, usize value_type_si static CHECK_RESULT int hash_map_bucket_add(HashMap *self, HashMapBucket *bucket, BufferView key, void *value, usize hash) { HashMapBucketNode *new_bucket_node; - return_if_error(scoped_allocator_alloc(self->allocator, + return_if_error(arena_allocator_alloc(self->allocator, sizeof(HashMapBucketNode*) + sizeof(hash) + sizeof(u32) + key.size + self->value_type_size, (void**)&new_bucket_node)); bucket_node_set_next(new_bucket_node, bucket->start); diff --git a/src/std/mem.c b/src/std/mem.c index f406176..95edcb9 100644 --- a/src/std/mem.c +++ b/src/std/mem.c @@ -1,5 +1,6 @@ #include "../../include/std/mem.h" #include +#include void am_memcpy(void *dest, const void *src, usize size) { memcpy(dest, src, size); @@ -16,3 +17,8 @@ bool am_memeql(const void *lhs, const void *rhs, usize size) { void am_memset(void *dest, int value, usize size) { memset(dest, value, size); } + +long am_pagesize() { + return sysconf(_SC_PAGESIZE); +} + diff --git a/src/std/scoped_allocator.c b/src/std/scoped_allocator.c deleted file mode 100644 index d8acbf6..0000000 --- a/src/std/scoped_allocator.c +++ /dev/null @@ -1,110 +0,0 @@ -#include "../../include/std/scoped_allocator.h" -#include "../../include/std/alloc.h" -#include "../../include/std/thread.h" -#include "../../include/std/log.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->mems, NULL); -} - -static void scoped_allocator_deinit_buffers(ScopedAllocator *self) { - void **mem; - void **mems_end; - mem = buffer_begin(&self->mems); - mems_end = buffer_end(&self->mems); - while(mem != mems_end) { - am_free(*mem); - ++mem; - } - buffer_deinit(&self->mems); -} - -void scoped_allocator_deinit(ScopedAllocator *self) { - self->current = NULL; - scoped_allocator_deinit_buffers(self); - scoped_allocator_node_deinit(&self->head); -} - -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; -} - -#define SCOPED_ALLOC_ALIGNMENT 8 - -int scoped_allocator_alloc(ScopedAllocator *self, usize size, void **mem) { - ScopedAllocatorNode *current; - usize alloc_size; - assert(self->current); - current = self->current; - - if(size >= ALLOC_NODE_SIZE) { - amal_log_error("scoped_allocator_alloc: tried to alloc memory of size %lu. Max allowed alloc size is %lu", size, ALLOC_NODE_SIZE); - return -1; - } - - alloc_size = size + align_ptr_ceil_offset(self->current->data + self->current->size, SCOPED_ALLOC_ALIGNMENT); - return_if_error(scoped_allocator_ensure_capacity_for(self, alloc_size)); - /* Reallocated (new node created) */ - if(self->current != current) { - *mem = self->current->data; - self->current->size += size; - } else { - *mem = align_ptr_ceil(self->current->data + self->current->size, SCOPED_ALLOC_ALIGNMENT); - self->current->size += alloc_size; - } - return 0; -} - -int scoped_allocator_add_mem(ScopedAllocator *self, usize *result_index) { - void *null_data; - null_data = NULL; - *result_index = buffer_get_size(&self->mems, sizeof(void*)); - return buffer_append(&self->mems, &null_data, sizeof(void*)); -} -- cgit v1.2.3