From 6534adc198ab79161a8a01bbfed8c72526dd7606 Mon Sep 17 00:00:00 2001 From: Matthew LeVan Date: Fri, 15 Sep 2023 16:30:28 -0400 Subject: [PATCH] wip: version `free` and `wfree` --- pkg/noun/v2/allocate.c | 172 +++++++++++++++++++++++++++++++++++++++++ pkg/noun/v2/allocate.h | 19 ++++- pkg/noun/v2/jets.c | 6 -- pkg/noun/v2/vortex.c | 2 + 4 files changed, 191 insertions(+), 8 deletions(-) diff --git a/pkg/noun/v2/allocate.c b/pkg/noun/v2/allocate.c index 74e54a975b..3469dc3aca 100644 --- a/pkg/noun/v2/allocate.c +++ b/pkg/noun/v2/allocate.c @@ -12,6 +12,178 @@ #include "trace.h" #include "vortex.h" +u3a_v2_road* u3a_v2_Road; + +/* _box_v2_make(): construct a box. + box_v - start addr of box + siz_w - size of allocated space adjacent to block + use_w - box's refcount +*/ +static u3a_v2_box* +_box_v2_make(void* box_v, c3_w siz_w, c3_w use_w) +{ + u3a_v2_box* box_u = box_v; + c3_w* box_w = box_v; + + u3_assert(siz_w >= u3a_v2_minimum); + + box_u->siz_w = siz_w; + box_w[siz_w - 1] = siz_w; /* stor size at end of allocation as well */ + box_u->use_w = use_w; + + return box_u; +} + +/* _box_v2_slot(): select the right free list to search for a block. + TODO: do we really need a loop to do this? + + so our free list logic looks like this: + siz_w < 6 words then [0] + siz_w < 16 then [1] + siz_w < 32 then [2] + siz_w < 64 then [3] + ... + siz_w > 4G then [26] +*/ +static c3_w +_box_v2_slot(c3_w siz_w) +{ + if ( siz_w < u3a_v2_minimum ) { + return 0; + } + + for (c3_w i_w = 1; i_w < u3a_v2_fbox_no; i_w++) { + if ( siz_w < 16 ) return i_w; + siz_w = (siz_w + 1) >> 1; + } + return u3a_v2_fbox_no - 1; +} + +/* _box_v2_attach(): attach a box to the free list. +*/ +static void +_box_v2_attach(u3a_v2_box* box_u) +{ + u3_assert(box_u->siz_w >= (1 + c3_wiseof(u3a_v2_fbox))); + u3_assert(0 != u3of(u3a_v2_fbox, box_u)); + + { + c3_w sel_w = _box_v2_slot(box_u->siz_w); + u3p(u3a_v2_fbox) fre_p = u3of(u3a_v2_fbox, box_u); + u3p(u3a_v2_fbox)* pfr_p = &u3R_v2->all.fre_p[sel_w]; + u3p(u3a_v2_fbox) nex_p = *pfr_p; + + u3to(u3a_v2_fbox, fre_p)->pre_p = 0; + u3to(u3a_v2_fbox, fre_p)->nex_p = nex_p; + if ( u3to(u3a_v2_fbox, fre_p)->nex_p ) { + u3to(u3a_v2_fbox, u3to(u3a_v2_fbox, fre_p)->nex_p)->pre_p = fre_p; + } + (*pfr_p) = fre_p; + } +} + +/* _box_v2_detach(): detach a box from the free list. +*/ +static void +_box_v2_detach(u3a_v2_box* box_u) +{ + u3p(u3a_v2_fbox) fre_p = u3of(u3a_v2_fbox, box_u); + u3p(u3a_v2_fbox) pre_p = u3to(u3a_v2_fbox, fre_p)->pre_p; + u3p(u3a_v2_fbox) nex_p = u3to(u3a_v2_fbox, fre_p)->nex_p; + + if ( nex_p ) { + if ( u3to(u3a_v2_fbox, nex_p)->pre_p != fre_p ) { + u3_assert(!"loom: corrupt"); + } + u3to(u3a_v2_fbox, nex_p)->pre_p = pre_p; + } + if ( pre_p ) { + if( u3to(u3a_v2_fbox, pre_p)->nex_p != fre_p ) { + u3_assert(!"loom: corrupt"); + } + u3to(u3a_v2_fbox, pre_p)->nex_p = nex_p; + } + else { + c3_w sel_w = _box_v2_slot(box_u->siz_w); + + if ( fre_p != u3R_v2->all.fre_p[sel_w] ) { + u3_assert(!"loom: corrupt"); + } + u3R_v2->all.fre_p[sel_w] = nex_p; + } +} + + +/* _box_v2_free(): free and coalesce. +*/ +static void +_box_v2_free(u3a_v2_box* box_u) +{ + c3_w* box_w = (c3_w *)(void *)box_u; + + u3_assert(box_u->use_w != 0); + box_u->use_w -= 1; + if ( 0 != box_u->use_w ) { + return; + } + + if ( c3y == u3a_v2_is_north(u3R_v2) ) { /* north */ + /* Try to coalesce with the block below. + */ + if ( box_w != u3a_v2_into(u3R_v2->rut_p) ) { + c3_w laz_w = *(box_w - 1); /* the size of a box stored at the end of its allocation */ + u3a_v2_box* pox_u = (u3a_v2_box*)(void *)(box_w - laz_w); /* the head of the adjacent box below */ + + if ( 0 == pox_u->use_w ) { + _box_v2_detach(pox_u); + _box_v2_make(pox_u, (laz_w + box_u->siz_w), 0); + + box_u = pox_u; + box_w = (c3_w*)(void *)pox_u; + } + } + + /* Try to coalesce with the block above, or the wilderness. + */ + if ( (box_w + box_u->siz_w) == u3a_v2_into(u3R_v2->hat_p) ) { + u3R_v2->hat_p = u3a_v2_outa(box_w); + } + else { + u3a_v2_box* nox_u = (u3a_v2_box*)(void *)(box_w + box_u->siz_w); + + if ( 0 == nox_u->use_w ) { + _box_v2_detach(nox_u); + _box_v2_make(box_u, (box_u->siz_w + nox_u->siz_w), 0); + } + _box_v2_attach(box_u); + } + } /* end north */ +} + +/* u3a_v2_wfree(): free storage. +*/ +void +u3a_v2_wfree(void* tox_v) +{ + _box_v2_free(u3a_v2_botox(tox_v)); +} + +/* u3a_v2_free(): free for aligned malloc. +*/ +void +u3a_v2_free(void* tox_v) +{ + if (NULL == tox_v) + return; + + c3_w* tox_w = tox_v; + c3_w pad_w = tox_w[-1]; + c3_w* org_w = tox_w - (pad_w + 1); + + // u3l_log("free %p %p", org_w, tox_w); + u3a_v2_wfree(org_w); +} + u3_noun u3a_v2_rewritten_noun(u3_noun som) { diff --git a/pkg/noun/v2/allocate.h b/pkg/noun/v2/allocate.h index bbce4ad121..5785ce2362 100644 --- a/pkg/noun/v2/allocate.h +++ b/pkg/noun/v2/allocate.h @@ -11,22 +11,23 @@ # define u3a_v2_botox u3a_botox # define u3a_v2_box u3a_box # define u3a_v2_cell u3a_cell +# define u3a_v2_fbox u3a_fbox # define u3a_v2_fbox_no u3a_fbox_no -# define u3a_v2_free u3a_free # define u3a_v2_heap u3a_heap # define u3a_v2_into u3a_into # define u3a_v2_is_cat u3a_is_cat # define u3a_v2_is_cell u3a_is_cell +# define u3a_v2_is_north u3a_is_north # define u3a_v2_is_pom u3a_is_pom # define u3a_v2_is_pug u3a_is_pug # define u3a_v2_malloc u3a_malloc +# define u3a_v2_minimum u3a_minimum # define u3a_v2_outa u3a_outa # define u3a_v2_pack_seek u3a_pack_seek # define u3a_v2_rewrite u3a_rewrite # define u3a_v2_rewrite_ptr u3a_rewrite_ptr # define u3a_v2_rewritten u3a_rewritten # define u3a_v2_road u3a_v2_road -# define u3a_v2_wfree u3a_wfree # define u3a_v2_to_off u3a_to_off # define u3a_v2_to_ptr u3a_to_ptr # define u3a_v2_to_wtr u3a_to_wtr @@ -106,6 +107,20 @@ **/ /** Allocation. **/ + /* Word-aligned allocation. + */ + /* u3a_v2_wfree(): free storage. + */ + void + u3a_v2_wfree(void* lag_v); + + /* C-style aligned allocation - *not* compatible with above. + */ + /* u3a_v2_free(): free for aligned malloc. + */ + void + u3a_v2_free(void* tox_v); + /* Reference and arena control. */ /* u3a_v2_rewrite_compact(): rewrite pointers in ad-hoc persistent road structures. diff --git a/pkg/noun/v2/jets.c b/pkg/noun/v2/jets.c index 91b23e5955..e70ef46abe 100644 --- a/pkg/noun/v2/jets.c +++ b/pkg/noun/v2/jets.c @@ -9,12 +9,6 @@ #include "pkg/noun/v2/hashtable.h" #include "pkg/noun/v2/vortex.h" -/** Data structures. -**/ - -/** Functions. -**/ - /* u3j_v2_rewrite_compact(): rewrite jet state for compaction. * * NB: u3R_v2->jed.han_p *must* be cleared (currently via u3j_v2_reclaim above) diff --git a/pkg/noun/v2/vortex.c b/pkg/noun/v2/vortex.c index 5a0d7cc4e2..382ed24192 100644 --- a/pkg/noun/v2/vortex.c +++ b/pkg/noun/v2/vortex.c @@ -5,6 +5,8 @@ #include "pkg/noun/v2/allocate.h" +u3v_v2_home* u3v_v2_Home; + /* u3v_v2_rewrite_compact(): rewrite arvo kernel for compaction. */ void