use the specified allocator for the element caches

This commit is contained in:
Alessandro Mauri 2025-08-29 19:24:52 +02:00
parent 4a690fdeb5
commit 5e5c912092
6 changed files with 51 additions and 37 deletions

2
TODO
View File

@ -5,7 +5,7 @@
[x] Port font system from C to C3 (rewrite1) [x] Port font system from C to C3 (rewrite1)
[ ] Update ARCHITECTURE.md [ ] Update ARCHITECTURE.md
[ ] Write a README.md [ ] Write a README.md
[ ] Use an arena allocator for cache [x] Use an arena allocator for cache
[ ] Do not redraw if there was no update (no layout and no draw) [ ] Do not redraw if there was no update (no layout and no draw)
[ ] Do command buffer damage tracking based on a context grid (see rxi writeup) [ ] Do command buffer damage tracking based on a context grid (see rxi writeup)
[x] Better handling of the active and focused widgets, try [x] Better handling of the active and focused widgets, try

View File

@ -25,6 +25,7 @@ alias IdTableEntry = map::Entry{Key, usz};
const usz CACHE_NCYCLES = (usz)(SIZE * 2.0/3.0); const usz CACHE_NCYCLES = (usz)(SIZE * 2.0/3.0);
struct Cache { struct Cache {
Allocator allocator;
BitArr present, used; BitArr present, used;
IdTable table; IdTable table;
Value[] pool; Value[] pool;
@ -43,19 +44,20 @@ macro Cache.cycle(&cache) @private {
} }
} }
fn void? Cache.init(&cache) fn void? Cache.init(&cache, Allocator allocator)
{ {
cache.table.init(allocator::heap(), capacity: SIZE); cache.allocator = allocator;
cache.table.init(allocator, capacity: SIZE);
// FIXME: this shit is SLOW // FIXME: this shit is SLOW
foreach (idx, bit : cache.used) { cache.used[idx] = false; } foreach (idx, bit : cache.used) { cache.used[idx] = false; }
foreach (idx, bit : cache.present) { cache.present[idx] = false; } foreach (idx, bit : cache.present) { cache.present[idx] = false; }
cache.pool = mem::new_array(Value, SIZE); cache.pool = allocator::new_array(allocator, Value, SIZE);
} }
fn void Cache.free(&cache) fn void Cache.free(&cache)
{ {
(void)cache.table.free(); (void)cache.table.free();
(void)mem::free(cache.pool); (void)allocator::free(cache.allocator, cache.pool);
} }
fn Value*? Cache.search(&cache, Key id) fn Value*? Cache.search(&cache, Key id)

View File

@ -9,21 +9,23 @@ import std::sort;
// TODO: specify the allocator // TODO: specify the allocator
struct Fifo { struct Fifo {
Allocator allocator;
Type[] arr; Type[] arr;
usz out; usz out;
usz count; usz count;
} }
fn void? Fifo.init(&fifo, usz size) fn void? Fifo.init(&fifo, usz size, Allocator allocator)
{ {
fifo.arr = mem::new_array(Type, size); fifo.allocator = allocator;
fifo.arr = allocator::new_array(fifo.allocator, Type, size);
fifo.out = 0; fifo.out = 0;
fifo.count = 0; fifo.count = 0;
} }
fn void Fifo.free(&fifo) fn void Fifo.free(&fifo)
{ {
(void)mem::free(fifo.arr); (void)allocator::free(fifo.allocator, fifo.arr);
} }
fn void? Fifo.enqueue(&fifo, Type *elem) fn void? Fifo.enqueue(&fifo, Type *elem)
@ -69,8 +71,8 @@ macro usz Fifo.len(&fifo) @operator(len)
fn void? Fifo.sort(&fifo) fn void? Fifo.sort(&fifo)
{ {
Type[] arr = mem::new_array(Type, fifo.count); Type[] arr = allocator::new_array(fifo.allocator, Type, fifo.count);
defer mem::free(arr); defer allocator::free(fifo.allocator, arr);
foreach(i, c: fifo) { foreach(i, c: fifo) {
arr[i] = c; arr[i] = c;

View File

@ -187,18 +187,18 @@ fn Elem*? Ctx.get_active_div(&ctx)
return ctx.cache.search(id); return ctx.cache.search(id);
} }
fn void? Ctx.init(&ctx) fn void? Ctx.init(&ctx, Allocator allocator)
{ {
ctx.tree.init(MAX_ELEMENTS)!; ctx.tree.init(MAX_ELEMENTS, allocator)!;
defer catch { (void)ctx.tree.free(); } defer catch { (void)ctx.tree.free(); }
ctx.cache.init()!; ctx.cache.init(allocator)!;
defer catch { (void)ctx.cache.free(); } defer catch { (void)ctx.cache.free(); }
ctx.cmd_queue.init(MAX_CMDS)!; ctx.cmd_queue.init(MAX_CMDS, allocator)!;
defer catch { (void)ctx.cmd_queue.free(); } defer catch { (void)ctx.cmd_queue.free(); }
ctx.styles.init(allocator::heap()); ctx.styles.init(allocator);
ctx.styles.register_style(&DEFAULT_STYLE, @str_hash("default")); ctx.styles.register_style(&DEFAULT_STYLE, @str_hash("default"));
defer catch { ctx.styles.free(); } defer catch { ctx.styles.free(); }

View File

@ -4,39 +4,43 @@ faultdef CANNOT_SHRINK, INVALID_REFERENCE, TREE_FULL, REFERENCE_NOT_PRESENT, INV
module vtree{ElemType}; module vtree{ElemType};
import std::core::mem; import std::core::mem;
import std::core::mem::allocator;
import std::io; import std::io;
struct VTree { struct VTree {
Allocator allocator;
usz elements; usz elements;
ElemType[] vector; // vector of element ids ElemType[] vector; // vector of element ids
isz[] refs, ordered_refs; isz[] refs, ordered_refs;
} }
macro VTree.ref_is_valid(&tree, isz ref) { return (ref >= 0 && ref < tree.refs.len); } macro VTree.ref_is_valid(&tree, isz ref) => (ref >= 0 && ref < tree.refs.len);
macro VTree.ref_is_present(&tree, isz ref) { return tree.refs[ref] >= 0; } macro VTree.ref_is_present(&tree, isz ref) => tree.refs[ref] >= 0;
macro VTree.size(&tree) { return tree.refs.len; } macro VTree.size(&tree) => tree.refs.len;
// macro to zero an elemen // macro to zero an element
macro @zero() macro @zero()
{ {
$if $assignable(0, ElemType): $if @assignable_to(0, ElemType):
return 0; return 0;
$else $else
return {}; return {};
$endif $endif
} }
fn void? VTree.init(&tree, usz size) fn void? VTree.init(&tree, usz size, Allocator allocator)
{ {
tree.vector = mem::new_array(ElemType, size); tree.allocator = allocator;
defer catch { (void)mem::free(tree.vector); }
tree.refs = mem::new_array(isz, size); tree.vector = allocator::new_array(tree.allocator, ElemType, size);
defer catch { (void)mem::free(tree.refs); } defer catch { (void)allocator::free(tree.allocator, tree.vector); }
tree.ordered_refs = mem::new_array(isz, size); tree.refs = allocator::new_array(tree.allocator, isz, size);
defer catch { (void)mem::free(tree.ordered_refs); } defer catch { (void)allocator::free(tree.allocator, tree.refs); }
tree.ordered_refs = allocator::new_array(tree.allocator, isz, size);
defer catch { (void)allocator::free(tree.allocator, tree.ordered_refs); }
// set all refs to -1, meaning invalid (free) element // set all refs to -1, meaning invalid (free) element
tree.refs[..] = -1; tree.refs[..] = -1;
@ -46,9 +50,9 @@ fn void? VTree.init(&tree, usz size)
fn void VTree.free(&tree) fn void VTree.free(&tree)
{ {
(void)mem::free(tree.vector); (void)allocator::free(tree.allocator, tree.vector);
(void)mem::free(tree.refs); (void)allocator::free(tree.allocator, tree.refs);
(void)mem::free(tree.ordered_refs); (void)allocator::free(tree.allocator, tree.ordered_refs);
} }
fn void VTree.pack(&tree) fn void VTree.pack(&tree)
@ -102,14 +106,14 @@ fn void? VTree.resize(&tree, usz newsize)
usz old_size = tree.size(); usz old_size = tree.size();
tree.vector = ((ElemType*)mem::realloc(tree.vector, newsize*ElemType.sizeof))[:newsize]; tree.vector = ((ElemType*)allocator::realloc(tree.allocator, tree.vector, newsize*ElemType.sizeof))[:newsize];
defer catch { (void)mem::free(tree.vector); } defer catch { (void)allocator::free(tree.allocator, tree.vector); }
tree.refs = ((isz*)mem::realloc(tree.refs, newsize*isz.sizeof))[:newsize]; tree.refs = ((isz*)allocator::realloc(tree.allocator, tree.refs, newsize*isz.sizeof))[:newsize];
defer catch { (void)mem::free(tree.refs); } defer catch { (void)allocator::free(tree.allocator, tree.refs); }
tree.ordered_refs = ((isz*)mem::realloc(tree.ordered_refs, newsize*isz.sizeof))[:newsize]; tree.ordered_refs = ((isz*)allocator::realloc(tree.allocator, tree.ordered_refs, newsize*isz.sizeof))[:newsize];
defer catch { (void)mem::free(tree.ordered_refs); } defer catch { (void)allocator::free(tree.allocator, tree.ordered_refs); }
if (newsize > tree.size()) { if (newsize > tree.size()) {
tree.vector[old_size..newsize-1] = @zero(); tree.vector[old_size..newsize-1] = @zero();

View File

@ -6,6 +6,7 @@ import std::time;
import std::collections::ringbuffer; import std::collections::ringbuffer;
import std::core::string; import std::core::string;
import std::ascii; import std::ascii;
import std::core::mem::allocator;
import sdlrenderer::ren; import sdlrenderer::ren;
import sdl3::sdl; import sdl3::sdl;
@ -58,8 +59,13 @@ const char[*] STYLESHEET_PATH = "resources/style.css";
fn int main(String[] args) fn int main(String[] args)
{ {
ArenaAllocator arena;
char[] mem = mem::new_array(char, 1024*1024);
defer (void)mem::free(mem);
arena.init(mem);
ugui::Ctx ui; ugui::Ctx ui;
ui.init()!!; ui.init(&arena)!!;
defer ui.free(); defer ui.free();
ren::Renderer ren; ren::Renderer ren;