Block allocator scratch
This commit is contained in:
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user