aboutsummaryrefslogtreecommitdiff
path: root/src/common.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-11-15 19:36:37 +0000
committergingerBill <bill@gingerbill.org>2020-11-15 19:36:37 +0000
commit0d6f5cec37e8815ff2e1c82575a05db98e4043d4 (patch)
tree0d116ce02890f1770b95f42323630c71fbfcf033 /src/common.cpp
parent17ec3e72a68b805fc202174722778545c956f433 (diff)
Implement custom temporary allocator using ring buffer
Diffstat (limited to 'src/common.cpp')
-rw-r--r--src/common.cpp130
1 files changed, 94 insertions, 36 deletions
diff --git a/src/common.cpp b/src/common.cpp
index 05ebdd4c5..0147f27d5 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -56,6 +56,14 @@ gb_inline isize align_formula_isize(isize size, isize align) {
}
return size;
}
+gb_inline void *align_formula_ptr(void *ptr, isize align) {
+ if (align > 0) {
+ uintptr result = (cast(uintptr)ptr) + align-1;
+ return (void *)(result - result%align);
+ }
+ return ptr;
+}
+
GB_ALLOCATOR_PROC(heap_allocator_proc);
@@ -380,6 +388,9 @@ typedef struct Arena {
#define ARENA_MIN_ALIGNMENT 16
#define ARENA_DEFAULT_BLOCK_SIZE (8*1024*1024)
+
+gb_global Arena permanent_arena = {};
+
void arena_init(Arena *arena, gbAllocator backing, isize block_size=ARENA_DEFAULT_BLOCK_SIZE) {
arena->backing = backing;
arena->block_size = block_size;
@@ -491,51 +502,98 @@ GB_ALLOCATOR_PROC(arena_allocator_proc) {
return ptr;
}
-struct SCOPED_TEMP_ARENA_MEMORY {
- Arena *arena;
- u8 * ptr;
- u8 * end;
- u8 * prev;
- isize total_used;
- isize block_count;
-
- SCOPED_TEMP_ARENA_MEMORY(Arena *the_arena) {
- GB_ASSERT(!the_arena->use_mutex);
- arena = the_arena;
- ptr = arena->ptr;
- end = arena->end;
- prev = arena->prev;
- total_used = arena->total_used;
- block_count = arena->blocks.count;
- }
- ~SCOPED_TEMP_ARENA_MEMORY() {
- if (arena->blocks.count != block_count) {
- for (isize i = block_count; i < arena->blocks.count; i++) {
- gb_free(arena->backing, arena->blocks[i]);
- }
- arena->blocks.count = block_count;
- }
- arena->ptr = ptr;
- arena->end = end;
- arena->prev = prev;
- arena->total_used = total_used;
- }
+
+gbAllocator permanent_allocator() {
+ return arena_allocator(&permanent_arena);
+ // return heap_allocator();
+}
+
+
+
+struct Temp_Allocator {
+ u8 *data;
+ isize len;
+ isize curr_offset;
+ gbAllocator backup_allocator;
+ Array<void *> leaked_allocations;
};
+gb_global Temp_Allocator temporary_allocator_data = {};
+void temp_allocator_init(Temp_Allocator *s, isize size) {
+ s->backup_allocator = heap_allocator();
+ s->data = cast(u8 *)gb_alloc_align(s->backup_allocator, size, 16);
+ s->curr_offset = 0;
+ s->leaked_allocations.allocator = s->backup_allocator;
+}
+void *temp_allocator_alloc(Temp_Allocator *s, isize size, isize alignment) {
+ size = align_formula_isize(size, alignment);
+ if (s->curr_offset+size <= s->len) {
+ u8 *start = s->data;
+ u8 *ptr = start + s->curr_offset;
+ ptr = cast(u8 *)align_formula_ptr(ptr, alignment);
+ // assume memory is zero
+
+ isize offset = ptr - start;
+ s->curr_offset = offset + size;
+ return ptr;
+ } else if (size <= s->len) {
+ u8 *start = s->data;
+ u8 *ptr = cast(u8 *)align_formula_ptr(start, alignment);
+ // assume memory is zero
+
+ isize offset = ptr - start;
+ s->curr_offset = offset + size;
+ return ptr;
+ }
-gb_global Arena permanent_arena = {};
-gb_global Arena temporary_arena = {};
+ void *ptr = gb_alloc_align(s->backup_allocator, size, alignment);
+ array_add(&s->leaked_allocations, ptr);
+ return ptr;
+}
-gbAllocator permanent_allocator() {
- return arena_allocator(&permanent_arena);
+void temp_allocator_free_all(Temp_Allocator *s) {
+ s->curr_offset = 0;
+ for_array(i, s->leaked_allocations) {
+ gb_free(s->backup_allocator, s->leaked_allocations[i]);
+ }
+ array_clear(&s->leaked_allocations);
+ gb_zero_size(s->data, s->len);
}
-gbAllocator temporary_allocator() {
- return arena_allocator(&temporary_arena);
+
+GB_ALLOCATOR_PROC(temp_allocator_proc) {
+ void *ptr = nullptr;
+ Temp_Allocator *s = cast(Temp_Allocator *)allocator_data;
+ GB_ASSERT_NOT_NULL(s);
+
+ switch (type) {
+ case gbAllocation_Alloc:
+ return temp_allocator_alloc(s, size, alignment);
+ case gbAllocation_Free:
+ break;
+ case gbAllocation_Resize:
+ if (size == 0) {
+ ptr = nullptr;
+ } else if (size <= old_size) {
+ ptr = old_memory;
+ } else {
+ ptr = temp_allocator_alloc(s, size, alignment);
+ gb_memmove(ptr, old_memory, old_size);
+ }
+ break;
+ case gbAllocation_FreeAll:
+ temp_allocator_free_all(s);
+ break;
+ }
+
+ return ptr;
}
-#define SCOPED_TEMPORARY_BLOCK() auto GB_DEFER_3(_SCOPED_TEMPORARY_BLOCK_) = SCOPED_TEMP_ARENA_MEMORY(&temporary_arena)
+
+gbAllocator temporary_allocator() {
+ return {temp_allocator_proc, &temporary_allocator_data};
+}