aboutsummaryrefslogtreecommitdiff
path: root/src/scoped_allocator.c
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-02-24 17:53:46 +0100
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commita307f17f44b461f58441926fcbf87883f17ebe61 (patch)
treeea03a634f06c33591c8afea5139e7e931d429cf7 /src/scoped_allocator.c
parent12e5135d95dc34fd7f7a7c50d6dbac453f252683 (diff)
Fixed CHECK_RESULT macro, use scoped allocator
Scoped allocator gives us better performance and cleanup code for error cases is much cleaner
Diffstat (limited to 'src/scoped_allocator.c')
-rw-r--r--src/scoped_allocator.c60
1 files changed, 60 insertions, 0 deletions
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 <assert.h>
+
+#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