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)
[ ] Update ARCHITECTURE.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 command buffer damage tracking based on a context grid (see rxi writeup)
[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);
struct Cache {
Allocator allocator;
BitArr present, used;
IdTable table;
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
foreach (idx, bit : cache.used) { cache.used[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)
{
(void)cache.table.free();
(void)mem::free(cache.pool);
(void)allocator::free(cache.allocator, cache.pool);
}
fn Value*? Cache.search(&cache, Key id)

View File

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

View File

@ -187,18 +187,18 @@ fn Elem*? Ctx.get_active_div(&ctx)
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(); }
ctx.cache.init()!;
ctx.cache.init(allocator)!;
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(); }
ctx.styles.init(allocator::heap());
ctx.styles.init(allocator);
ctx.styles.register_style(&DEFAULT_STYLE, @str_hash("default"));
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};
import std::core::mem;
import std::core::mem::allocator;
import std::io;
struct VTree {
Allocator allocator;
usz elements;
ElemType[] vector; // vector of element ids
isz[] refs, ordered_refs;
}
macro VTree.ref_is_valid(&tree, isz ref) { return (ref >= 0 && ref < tree.refs.len); }
macro VTree.ref_is_present(&tree, isz ref) { return tree.refs[ref] >= 0; }
macro VTree.size(&tree) { return 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) => tree.refs[ref] >= 0;
macro VTree.size(&tree) => tree.refs.len;
// macro to zero an elemen
// macro to zero an element
macro @zero()
{
$if $assignable(0, ElemType):
$if @assignable_to(0, ElemType):
return 0;
$else
return {};
$endif
}
fn void? VTree.init(&tree, usz size)
fn void? VTree.init(&tree, usz size, Allocator allocator)
{
tree.vector = mem::new_array(ElemType, size);
defer catch { (void)mem::free(tree.vector); }
tree.allocator = allocator;
tree.refs = mem::new_array(isz, size);
defer catch { (void)mem::free(tree.refs); }
tree.vector = allocator::new_array(tree.allocator, ElemType, size);
defer catch { (void)allocator::free(tree.allocator, tree.vector); }
tree.ordered_refs = mem::new_array(isz, size);
defer catch { (void)mem::free(tree.ordered_refs); }
tree.refs = allocator::new_array(tree.allocator, isz, size);
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
tree.refs[..] = -1;
@ -46,9 +50,9 @@ fn void? VTree.init(&tree, usz size)
fn void VTree.free(&tree)
{
(void)mem::free(tree.vector);
(void)mem::free(tree.refs);
(void)mem::free(tree.ordered_refs);
(void)allocator::free(tree.allocator, tree.vector);
(void)allocator::free(tree.allocator, tree.refs);
(void)allocator::free(tree.allocator, tree.ordered_refs);
}
fn void VTree.pack(&tree)
@ -102,14 +106,14 @@ fn void? VTree.resize(&tree, usz newsize)
usz old_size = tree.size();
tree.vector = ((ElemType*)mem::realloc(tree.vector, newsize*ElemType.sizeof))[:newsize];
defer catch { (void)mem::free(tree.vector); }
tree.vector = ((ElemType*)allocator::realloc(tree.allocator, tree.vector, newsize*ElemType.sizeof))[:newsize];
defer catch { (void)allocator::free(tree.allocator, tree.vector); }
tree.refs = ((isz*)mem::realloc(tree.refs, newsize*isz.sizeof))[:newsize];
defer catch { (void)mem::free(tree.refs); }
tree.refs = ((isz*)allocator::realloc(tree.allocator, tree.refs, newsize*isz.sizeof))[:newsize];
defer catch { (void)allocator::free(tree.allocator, tree.refs); }
tree.ordered_refs = ((isz*)mem::realloc(tree.ordered_refs, newsize*isz.sizeof))[:newsize];
defer catch { (void)mem::free(tree.ordered_refs); }
tree.ordered_refs = ((isz*)allocator::realloc(tree.allocator, tree.ordered_refs, newsize*isz.sizeof))[:newsize];
defer catch { (void)allocator::free(tree.allocator, tree.ordered_refs); }
if (newsize > tree.size()) {
tree.vector[old_size..newsize-1] = @zero();

View File

@ -6,6 +6,7 @@ import std::time;
import std::collections::ringbuffer;
import std::core::string;
import std::ascii;
import std::core::mem::allocator;
import sdlrenderer::ren;
import sdl3::sdl;
@ -58,8 +59,13 @@ const char[*] STYLESHEET_PATH = "resources/style.css";
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;
ui.init()!!;
ui.init(&arena)!!;
defer ui.free();
ren::Renderer ren;