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
|
#if OS_WASM
|
||||||
|
BlockArena ScratchArenas[4];
|
||||||
API void InitScratch() {
|
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
|
#else
|
||||||
thread_local VirtualArena ScratchArenas[4];
|
thread_local VirtualArena ScratchArenas[4];
|
||||||
|
|||||||
@@ -98,16 +98,43 @@ API void Release(VirtualArena *arena);
|
|||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// Scratch
|
// Scratch
|
||||||
#if OS_WASM
|
#if OS_WASM
|
||||||
|
extern BlockArena ScratchArenas[4];
|
||||||
|
API BlockArena *GetScratchEx(BlockArena **conflicts, int conflict_count);
|
||||||
struct Scratch {
|
struct Scratch {
|
||||||
BlockArena arena = {};
|
BlockArena *arena;
|
||||||
Scratch() {}
|
U8 *p;
|
||||||
Scratch(BlockArena *conflict) {}
|
Scratch() {arena = &ScratchArenas[0]; if (!arena->blocks) Init(arena); p = arena->start; arena->refs += 1;}
|
||||||
Scratch(BlockArena *c1, BlockArena *c2) {}
|
Scratch(BlockArena *conflict) {
|
||||||
Scratch(Allocator conflict) {}
|
BlockArena *conf[] = {conflict};
|
||||||
Scratch(Allocator c1, Allocator c2) {}
|
arena = GetScratchEx(conf, Lengthof(conf));
|
||||||
~Scratch() { Release(&arena); }
|
if (!arena->blocks) Init(arena);
|
||||||
operator BlockArena *() { return &arena; }
|
p = arena->start;
|
||||||
operator Allocator() { return arena; }
|
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
|
private: // @Note: Disable copy constructors, cause its error prone
|
||||||
Scratch(Scratch &arena);
|
Scratch(Scratch &arena);
|
||||||
Scratch(Scratch &arena, Scratch &a2);
|
Scratch(Scratch &arena, Scratch &a2);
|
||||||
|
|||||||
Reference in New Issue
Block a user