From b2c3cac73d386a7a33e0afefbc16c8c8b116a29a Mon Sep 17 00:00:00 2001 From: KK Date: Fri, 3 Jul 2026 21:14:23 +0200 Subject: [PATCH] Block allocator scratch --- src/basic_alloc.cpp | 27 +++++++++++++++++++++++++++ src/basic_alloc.h | 45 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/basic_alloc.cpp b/src/basic_alloc.cpp index 0dfd6fd..3de2ad7 100644 --- a/src/basic_alloc.cpp +++ b/src/basic_alloc.cpp @@ -331,7 +331,34 @@ API void *BlockArenaAllocatorProc(void *object, int kind, void *p, size_t size) } #if OS_WASM +BlockArena ScratchArenas[4]; API void InitScratch() { + for (int i = 0; i < 4; i += 1) { + if (!ScratchArenas[i].blocks) Init(&ScratchArenas[i]); + } +} + +API BlockArena *GetScratchEx(BlockArena **conflicts, int conflict_count) { + BlockArena *unoccupied = 0; + for (int i = 0; i < Lengthof(ScratchArenas); i += 1) { + BlockArena *from_pool = &ScratchArenas[i]; + unoccupied = from_pool; + for (int conflict_i = 0; conflict_i < conflict_count; conflict_i += 1) { + BlockArena *from_conflict = conflicts[conflict_i]; + if (from_pool == from_conflict) { + unoccupied = 0; + break; + } + } + + if (unoccupied) { + break; + } + } + + // Failed to get free scratch memory, this is a fatal error, this shouldnt happen + Assert(unoccupied); + return unoccupied; } #else thread_local VirtualArena ScratchArenas[4]; diff --git a/src/basic_alloc.h b/src/basic_alloc.h index c7cf20b..fde8de5 100644 --- a/src/basic_alloc.h +++ b/src/basic_alloc.h @@ -98,16 +98,43 @@ API void Release(VirtualArena *arena); /////////////////////////////// // Scratch #if OS_WASM +extern BlockArena ScratchArenas[4]; +API BlockArena *GetScratchEx(BlockArena **conflicts, int conflict_count); struct Scratch { - BlockArena arena = {}; - Scratch() {} - Scratch(BlockArena *conflict) {} - Scratch(BlockArena *c1, BlockArena *c2) {} - Scratch(Allocator conflict) {} - Scratch(Allocator c1, Allocator c2) {} - ~Scratch() { Release(&arena); } - operator BlockArena *() { return &arena; } - operator Allocator() { return arena; } + BlockArena *arena; + U8 *p; + Scratch() {arena = &ScratchArenas[0]; if (!arena->blocks) Init(arena); p = arena->start; arena->refs += 1;} + Scratch(BlockArena *conflict) { + BlockArena *conf[] = {conflict}; + arena = GetScratchEx(conf, Lengthof(conf)); + if (!arena->blocks) Init(arena); + p = arena->start; + arena->refs += 1; + } + Scratch(BlockArena *c1, BlockArena *c2) { + BlockArena *conf[] = {c1, c2}; + arena = GetScratchEx(conf, Lengthof(conf)); + if (!arena->blocks) Init(arena); + p = arena->start; + arena->refs += 1; + } + Scratch(Allocator conflict) { + BlockArena *conf[] = {(BlockArena *)conflict.object}; + arena = GetScratchEx(conf, Lengthof(conf)); + if (!arena->blocks) Init(arena); + p = arena->start; + arena->refs += 1; + } + Scratch(Allocator c1, Allocator c2) { + BlockArena *conf[] = {(BlockArena *)c1.object, (BlockArena *)c2.object}; + arena = GetScratchEx(conf, Lengthof(conf)); + if (!arena->blocks) Init(arena); + p = arena->start; + arena->refs += 1; + } + ~Scratch() { Unwind(arena, p); arena->refs -= 1; } + operator BlockArena *() { return arena; } + operator Allocator() { return *arena; } private: // @Note: Disable copy constructors, cause its error prone Scratch(Scratch &arena); Scratch(Scratch &arena, Scratch &a2);