Skip to content

Commit

Permalink
wip: version free and wfree
Browse files Browse the repository at this point in the history
  • Loading branch information
matthew-levan committed Sep 15, 2023
1 parent ef7b8a6 commit 4867892
Show file tree
Hide file tree
Showing 2 changed files with 187 additions and 2 deletions.
170 changes: 170 additions & 0 deletions pkg/noun/v2/allocate.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,176 @@
#include "trace.h"
#include "vortex.h"

/* _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->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->all.fre_p[sel_w] ) {
u3_assert(!"loom: corrupt");
}
u3R->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)
{
Expand Down
19 changes: 17 additions & 2 deletions pkg/noun/v2/allocate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -106,6 +107,20 @@
**/
/** Allocation.
**/
/* Word-aligned allocation.
*/
/* u3a_wfree(): free storage.
*/
void
u3a_wfree(void* lag_v);

/* C-style aligned allocation - *not* compatible with above.
*/
/* u3a_free(): free for aligned malloc.
*/
void
u3a_free(void* tox_v);

/* Reference and arena control.
*/
/* u3a_v2_rewrite_compact(): rewrite pointers in ad-hoc persistent road structures.
Expand Down

0 comments on commit 4867892

Please sign in to comment.