From d10b72057e1738a0c59af1f92ab5ab0b6efa65b0 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sun, 1 Jan 2023 00:38:19 +0100 Subject: [PATCH] Block based arena --- build.bat | 6 +++- core_arena.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++++ core_generated.cpp | 2 -- 3 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 core_arena.cpp diff --git a/build.bat b/build.bat index 8de3cfc..5eeb352 100644 --- a/build.bat +++ b/build.bat @@ -1,10 +1,14 @@ @echo off +set clang-flags=-O0 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o main.exe -Wl,user32.lib + pushd %~dp0 rem cl main.cpp -I.. user32.lib -clang core_main.cpp -O0 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o main.exe -Wl,user32.lib +rem clang core_main.cpp %clang-flags% rem ubuntu run clang core_main.cpp -O0 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o core.out +clang core_arena.cpp %clang-flags% + rem clang test.cpp rem main.exe -testing diff --git a/core_arena.cpp b/core_arena.cpp new file mode 100644 index 0000000..a06de78 --- /dev/null +++ b/core_arena.cpp @@ -0,0 +1,83 @@ +#include "base.cpp" + +struct Arena_Block { + Arena_Block *next; + Arena_Block *prev; + size_t cap; + size_t len; + uint8_t memory[]; +}; + +constexpr size_t default_block_size = mib(1); +struct Arena_Block_Based : Allocator { + Arena_Block *first; + Arena_Block *last; + Arena_Block *first_free; + Allocator *block_allocator; + size_t alignment; +}; + +static void arena_add_block(Arena_Block_Based *arena, size_t min_size) { + Arena_Block *block = 0; + for (Arena_Block *it = arena->first_free; it; it = it->next) { + if (it->cap > min_size) { + block = it; + DLL_STACK_REMOVE(arena->first_free, it); + break; + } + } + + if (!block) { + block = (Arena_Block *)allocate_size(arena->block_allocator, sizeof(Arena_Block) + min_size + default_alignment, false); + block->cap = min_size + default_alignment; + } + + block->len = 0; + block->next = 0; + block->prev = 0; + DLL_QUEUE_ADD(arena->first, arena->last, block); +} + +static void *block_arena_push_size(Arena_Block_Based *arena, size_t size) { + size_t generous_size = size + arena->alignment; + if (!arena->last || (arena->last->len + generous_size > arena->last->cap)) { + assert(arena->block_allocator); + size_t block_size = max(default_block_size, generous_size); + arena_add_block(arena, block_size); + } + + Arena_Block *L = arena->last; + size_t adjusted_len = align_up((size_t)L->memory + L->len, arena->alignment) - (size_t)L->memory; + assert(((int64_t)adjusted_len - (int64_t)L->len) > 0); + assert(((int64_t)adjusted_len - (int64_t)L->len) <= arena->alignment); + L->len = adjusted_len; + + uint8_t *result = L->memory + L->len; + L->len += size; + return (void *)result; +} + +static Arena_Block_Based make_arena_block_based(Allocator *allocator) { + Arena_Block_Based result = {}; + result.block_allocator = allocator; + result.alignment = default_alignment; + result.allocate = (Allocator::Allocate *)block_arena_push_size; + result.deallocate = (Allocator::Deallocate *)deallocate_stub; + return result; +} + +struct CRT_Heap : Allocator {}; +static void *crt_allocate(Allocator *allocator, size_t size) { return malloc(size); } +static void crt_deallocate(Allocator *allocator, void *p) { return free(p); } +static CRT_Heap make_crt_heap() { + CRT_Heap result = {}; + result.allocate = crt_allocate; + result.deallocate = crt_deallocate; + return result; +} + +int main() { + CRT_Heap heap = make_crt_heap(); + Arena_Block_Based arena = make_arena_block_based(&heap); + void *result = allocate_size(&arena, 32); +} \ No newline at end of file diff --git a/core_generated.cpp b/core_generated.cpp index 5f657ba..6bc0372 100644 --- a/core_generated.cpp +++ b/core_generated.cpp @@ -1,6 +1,4 @@ - - /*#import meta print("Operator_Info op_info_table[] = {")