Block based arena

This commit is contained in:
Krzosa Karol
2023-01-01 00:38:19 +01:00
parent d5179bb596
commit d10b72057e
3 changed files with 88 additions and 3 deletions

View File

@@ -1,10 +1,14 @@
@echo off @echo off
set clang-flags=-O0 -Wall -Wno-unused-function -fno-exceptions -fdiagnostics-absolute-paths -g -o main.exe -Wl,user32.lib
pushd %~dp0 pushd %~dp0
rem cl main.cpp -I.. user32.lib 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 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 clang test.cpp
rem main.exe -testing rem main.exe -testing

83
core_arena.cpp Normal file
View File

@@ -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);
}

View File

@@ -1,6 +1,4 @@
/*#import meta /*#import meta
print("Operator_Info op_info_table[] = {") print("Operator_Info op_info_table[] = {")