mirror of
https://github.com/ilyakooo0/urbit.git
synced 2025-01-03 04:40:50 +03:00
Various fixes and improvements.
This commit is contained in:
parent
7dc457df4e
commit
75e61cf916
261
f/meme.c
Normal file
261
f/meme.c
Normal file
@ -0,0 +1,261 @@
|
||||
/* f/rail.c
|
||||
**
|
||||
** This file is in the public domain.
|
||||
*/
|
||||
#include "all.h"
|
||||
|
||||
#ifdef U2_LEAK_DEBUG
|
||||
c3_w COD_w;
|
||||
#endif
|
||||
|
||||
|
||||
//////// Basic allocation.
|
||||
|
||||
|
||||
/* _me_box_make(): make a box.
|
||||
*/
|
||||
c3_w
|
||||
_me_box_make()
|
||||
|
||||
/* _me_free_slot(): select the right free list to search for a block.
|
||||
*/
|
||||
c3_w
|
||||
_me_free_slot(c3_w siz_w)
|
||||
{
|
||||
if ( siz_w < 8 ) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
c3_w i_w = 1;
|
||||
|
||||
while ( 1 ) {
|
||||
if ( i_w == u2_me_free_no ) {
|
||||
return (i_w - 1);
|
||||
}
|
||||
if ( siz_w < 16 ) {
|
||||
return i_w;
|
||||
}
|
||||
siz_w = (siz_w + 1) >> 1;
|
||||
i_w += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* u2_me_walloc(): allocate storage measured in words.
|
||||
*/
|
||||
void*
|
||||
u2_me_walloc(c3_w len_w)
|
||||
{
|
||||
c3_w siz_w = c3_max(u2_me_minimum, u2_me_boxed(len_w));
|
||||
c3_w sel_w = _me_free_slot(siz_w);
|
||||
|
||||
if ( (sel_w != 0) && (sel_w != u2_me_free_no - 1) ) {
|
||||
sel_w += 1;
|
||||
}
|
||||
|
||||
while ( 1 ) {
|
||||
u2_me_free* pfr_u = u2R->all.fre_u[sel_w];
|
||||
c3_w* box_w;
|
||||
|
||||
if ( 0 == pfr_u ) {
|
||||
if ( sel_w < (u2_me_free_no - 1) ) {
|
||||
sel_w += 1;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* Nothing in top free list. Chip away at the hat.
|
||||
*/
|
||||
if ( u2_no == u2_me_open(siz_w) ) {
|
||||
u2_loop_signal_memory();
|
||||
}
|
||||
else {
|
||||
box_w = u2R->lay.hat_w;
|
||||
u2R->lay.hat_w += siz_w;
|
||||
|
||||
_me_box_make(
|
||||
|
||||
box_r = u2_rail_hat_r(ral_r);
|
||||
u2_rail_hat_r(ral_r) += siz_w;
|
||||
|
||||
_rl_bloq_make(ral_r, box_r, siz_w, 1);
|
||||
_rl_live_grab(ral_r, siz_w);
|
||||
|
||||
_rl_bloq_cheq(box_r);
|
||||
return (box_r + c3_wiseof(u2_loom_rail_box));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pfr_r = u2_aftr(sop_r, u2_loom_soup, fre_r) + sel_w;
|
||||
|
||||
while ( 1 ) {
|
||||
u2_ray fre_r = *u2_at_ray(pfr_r);
|
||||
u2_ray box_r;
|
||||
|
||||
if ( 0 == fre_r ) {
|
||||
if ( sel_w < (u2_me_free_no - 1) ) {
|
||||
sel_w += 1;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* Nothing in top free list. Chip away at the hat.
|
||||
*/
|
||||
if ( u2_no == u2_rl_open(ral_r, siz_w) ) {
|
||||
#if 1
|
||||
u2_loop_signal_memory();
|
||||
#else
|
||||
/* Yo, our rail is totally full.
|
||||
*/
|
||||
printf("lose: siz_w: %d sel_w: %d\n", siz_w, sel_w);
|
||||
u2_rl_dump(ral_r);
|
||||
|
||||
u2_ho_warn_here();
|
||||
// XX: integrate with integral wire.
|
||||
//
|
||||
// A bunch of testing is needed to make this actually work.
|
||||
// return 0;
|
||||
c3_assert(0);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
box_r = u2_rail_hat_r(ral_r);
|
||||
u2_rail_hat_r(ral_r) += siz_w;
|
||||
|
||||
_rl_bloq_make(ral_r, box_r, siz_w, 1);
|
||||
_rl_live_grab(ral_r, siz_w);
|
||||
|
||||
_rl_bloq_cheq(box_r);
|
||||
return (box_r + c3_wiseof(u2_loom_rail_box));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( siz_w > u2_rail_hut_siz(fre_r) ) {
|
||||
/* This free block is too small. Continue searching.
|
||||
*/
|
||||
pfr_r = u2_aftr(fre_r, u2_loom_rail_hut, nex_r);
|
||||
}
|
||||
else {
|
||||
/* We have found a free block of adequate size. Remove it
|
||||
** from the free list.
|
||||
*/
|
||||
box_r = fre_r;
|
||||
|
||||
{
|
||||
u2_ray pre_r = u2_rail_hut_pre(box_r);
|
||||
u2_ray nex_r = u2_rail_hut_nex(box_r);
|
||||
|
||||
c3_assert((0 == pre_r) ||
|
||||
(u2_at_ray(pfr_r) == &u2_rail_hut_nex(pre_r)));
|
||||
*u2_at_ray(pfr_r) = nex_r;
|
||||
|
||||
if ( 0 != nex_r ) {
|
||||
u2_rail_hut_pre(nex_r) = pre_r;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (siz_w + 6) < u2_rail_hut_siz(box_r) ) {
|
||||
/* Split the block.
|
||||
*/
|
||||
u2_ray end_r = (box_r + siz_w);
|
||||
|
||||
_rl_bloq_make(ral_r, end_r, u2_rail_hut_siz(fre_r) - siz_w, 0);
|
||||
_rl_bloq_attach(ral_r, end_r);
|
||||
_rl_bloq_make(ral_r, box_r, siz_w, 1);
|
||||
|
||||
_rl_live_grab(ral_r, siz_w);
|
||||
}
|
||||
else {
|
||||
c3_assert(u2_rail_box_use(box_r) == 0);
|
||||
u2_rail_box_use(box_r) = 1;
|
||||
# ifdef U2_LEAK_DEBUG
|
||||
*u2_at_ray(box_r + 2) = COD_w;
|
||||
# endif
|
||||
|
||||
_rl_live_grab(ral_r, u2_rail_hut_siz(box_r));
|
||||
}
|
||||
_rl_bloq_cheq(box_r);
|
||||
return (box_r + c3_wiseof(u2_loom_rail_box));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* u2_me_malloc(): allocate storage measured in bytes.
|
||||
*/
|
||||
void*
|
||||
u2_me_malloc(c3_w len_w);
|
||||
|
||||
/* u2_me_free(): free storage.
|
||||
*/
|
||||
void
|
||||
u2_me_free(void* lag_v);
|
||||
{
|
||||
c3_w* lag_w = lag_v;
|
||||
return;
|
||||
}
|
||||
|
||||
//////// Atoms from proto-atoms.
|
||||
|
||||
/* Basic allocation.
|
||||
*/
|
||||
/* u2_me_walloc(): allocate storage measured in words.
|
||||
*/
|
||||
void*
|
||||
u2_me_walloc(c3_w len_w);
|
||||
|
||||
/* u2_me_malloc(): allocate storage measured in bytes.
|
||||
*/
|
||||
void*
|
||||
u2_me_malloc(c3_w len_w);
|
||||
|
||||
/* u2_me_free(): free storage.
|
||||
*/
|
||||
void
|
||||
u2_me_free(void* lag_v);
|
||||
|
||||
|
||||
|
||||
/* u2_me_slab(): create a length-bounded proto-atom.
|
||||
*/
|
||||
c3_w*
|
||||
u2_me_slab(c3_w len_w)
|
||||
{
|
||||
u2_ray nov_r = u2_rl_ralloc(ral_r, (len_w + c3_wiseof(u2_loom_atom)));
|
||||
u2_atom nov = u2_pug_of(nov_r, 0);
|
||||
|
||||
*u2_at_dog_mug(nov) = 0;
|
||||
*u2_at_pug_len(nov) = len_w;
|
||||
|
||||
/* Clear teh slab.
|
||||
*/
|
||||
{
|
||||
c3_w i_w;
|
||||
|
||||
for ( i_w=0; i_w < len_w; i_w++ ) {
|
||||
*u2_at_pug_buf(nov, i_w) = 0;
|
||||
}
|
||||
}
|
||||
return (nov_r + c3_wiseof(u2_loom_atom));
|
||||
|
||||
/* u2_me_slaq(): u2_me_slaq() with a defined blocksize.
|
||||
*/
|
||||
c3_w*
|
||||
u2_me_slaq(c3_g met_g, c3_w len_w);
|
||||
|
||||
/* u2_me_malt(): measure and finish a proto-atom.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_malt(c3_w* sal_w);
|
||||
|
||||
/* u2_me_moot(): finish a pre-measured proto-atom; dangerous.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_moot(c3_w* sal_w);
|
||||
|
||||
/* u2_me_mint(): finish a measured proto-atom.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_mint(c3_w* sal_w, c3_w len_w);
|
625
include/f/meme.h
625
include/f/meme.h
@ -4,19 +4,18 @@
|
||||
*/
|
||||
/** Tuning and configuration.
|
||||
**/
|
||||
# define u2_meme_free_no 28
|
||||
# define u2_me_free_no 28
|
||||
|
||||
# undef U2_LEAK_DEBUG
|
||||
# ifdef U2_LEAK_DEBUG
|
||||
# undef U2_MEMORY_DEBUG
|
||||
# ifdef U2_MEMORY_DEBUG
|
||||
# define u2_leak_on(x) (COD_w = x)
|
||||
extern c3_w COD_w;
|
||||
# define u2_leak_off (COD_w = 0)
|
||||
# endif
|
||||
|
||||
|
||||
/** Data structures.
|
||||
**/
|
||||
/* A classic allocation box.
|
||||
/* u2_me_box{}: classic allocation box.
|
||||
**
|
||||
** The box size is also stored at the end of the box in classic
|
||||
** bad ass malloc style. Hence a box is:
|
||||
@ -30,36 +29,45 @@
|
||||
**
|
||||
** Do not attempt to adjust this structure!
|
||||
*/
|
||||
typedef struct _u2_rbox {
|
||||
c3_w siz_w; // size of this box
|
||||
c3_w use_w; // reference count; free if 0
|
||||
typedef struct _u2_me_box {
|
||||
c3_w siz_w; // size of this box
|
||||
c3_w use_w; // reference count; free if 0
|
||||
# ifdef U2_LEAK_DEBUG
|
||||
c3_w cod_w; // allocation code
|
||||
c3_w cod_w; // tracing code
|
||||
# endif
|
||||
} u2_rbox;
|
||||
} u2_me_box;
|
||||
|
||||
/* A free node. Also sets the minimum possible box size.
|
||||
*/
|
||||
typedef struct _u2_rfre {
|
||||
u2_rbox box_u;
|
||||
struct _u2_rfre* pre_u;
|
||||
struct _u2_rfre* nex_u;
|
||||
} u2_rfre;
|
||||
# define u2_me_boxed(len_w) (len_w + c3_wiseof(u2_me_box) + 1)
|
||||
|
||||
/* An execution context.
|
||||
/* u2_me_free{}: free node in heap. Sets minimum node size.
|
||||
**
|
||||
** XXO: pre_u and nex_u should live in box.
|
||||
*/
|
||||
typedef struct _u2_road {
|
||||
struct _u2_road *par_u; // parent road
|
||||
typedef struct _u2_me_free {
|
||||
u2_me_box box_u;
|
||||
struct _u2_me_free* pre_u;
|
||||
struct _u2_me_free* nex_u;
|
||||
} u2_me_free;
|
||||
|
||||
# define u2_me_minimum (c3_wiseof(u2_me_free))
|
||||
|
||||
/* u2_me_road{}: allocation and execution context.
|
||||
*/
|
||||
typedef struct _u2_me_road {
|
||||
struct _u2_me_road* par_u; // parent road
|
||||
|
||||
struct { // layout information
|
||||
void* cap_v; // top of transient region
|
||||
void* hat_v; // top of durable region
|
||||
void* mat_v; // bottom of transient region
|
||||
void* rut_v; // bottom of durable region
|
||||
c3_w* cap_w; // top of transient region
|
||||
c3_w* hat_w; // top of durable region
|
||||
c3_w* mat_w; // bottom of transient region
|
||||
c3_w* rut_w; // bottom of durable region
|
||||
} lay;
|
||||
|
||||
struct { // allocation pools
|
||||
u2_rfre* fre_u[u2_meme_free_no]; // by node size, doubling
|
||||
u2_me_free* fre_u[u2_me_free_no]; // heap by node size log
|
||||
# ifdef U2_MEMORY_DEBUG
|
||||
c3_w liv_w;
|
||||
# endif
|
||||
} all;
|
||||
|
||||
struct { // jet dashboard
|
||||
@ -80,126 +88,289 @@
|
||||
|
||||
struct { // memoization
|
||||
u2_noun sav; // (map (pair term noun) noun)
|
||||
};
|
||||
} u2_road;
|
||||
} cax;
|
||||
} u2_me_road;
|
||||
typedef u2_me_road u2_road;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct _u2_town {
|
||||
u2_town* par_u;
|
||||
} u2_town;
|
||||
|
||||
/** Data types.
|
||||
/** Globals.
|
||||
**/
|
||||
/** Ray types.
|
||||
/* u2_Home / u2H: root of thread.
|
||||
*/
|
||||
c3_global u2_road* u2_Home;
|
||||
# define u2H u2_Home
|
||||
|
||||
/* u2_Road / u2R: current road.
|
||||
*/
|
||||
c3_global u2_road* u2_Road;
|
||||
# define u2R u2_Road
|
||||
|
||||
|
||||
/** Functions.
|
||||
**/
|
||||
/** Arena configuration.
|
||||
**/
|
||||
/* u2_rail: an allocation control frame.
|
||||
/* u2_me_boot(): make u2R and u2H from nothing.
|
||||
*/
|
||||
typedef u2_ray u2_rail;
|
||||
void
|
||||
u2_me_boot(void* mem_v, c3_w len_w);
|
||||
|
||||
/* u2_wire: an execution context, inheriting rail
|
||||
/* u2_me_check(): checkpoint memory to file.
|
||||
*/
|
||||
typedef u2_ray u2_wire;
|
||||
void
|
||||
u2_me_check(void);
|
||||
|
||||
/** Structures - in loom space.
|
||||
/* u2_me_fall(): return to parent road.
|
||||
*/
|
||||
void
|
||||
u2_me_fall(void):
|
||||
|
||||
/* u2_me_leap(): advance to inner road.
|
||||
*/
|
||||
void
|
||||
u2_me_leap(void);
|
||||
|
||||
/* u2_me_flog(): release the can, setting cap to mat.
|
||||
*/
|
||||
void
|
||||
u2_me_flog(void);
|
||||
|
||||
|
||||
/** Allocation.
|
||||
**/
|
||||
/* Base rail.
|
||||
/* Basic allocation.
|
||||
*/
|
||||
typedef struct _u2_loom_rail {
|
||||
u2_ray cap_r; // top of transient region
|
||||
u2_ray hat_r; // top of new durable region
|
||||
u2_ray mat_r; // bottom of transient region
|
||||
u2_ray rut_r; // bottom of new durable region
|
||||
c3_m hip_m; // memory model in durable; c3__rock, c3__sand
|
||||
} u2_loom_rail;
|
||||
/* u2_me_walloc(): allocate storage measured in words.
|
||||
*/
|
||||
void*
|
||||
u2_me_walloc(c3_w len_w);
|
||||
|
||||
# define u2_rail_cap_r(ral_r) *u2_at(ral_r, u2_loom_rail, cap_r)
|
||||
# define u2_rail_hat_r(ral_r) *u2_at(ral_r, u2_loom_rail, hat_r)
|
||||
# define u2_rail_mat_r(ral_r) *u2_at(ral_r, u2_loom_rail, mat_r)
|
||||
# define u2_rail_rut_r(ral_r) *u2_at(ral_r, u2_loom_rail, rut_r)
|
||||
# define u2_rail_hip_m(ral_r) *u2_at(ral_r, u2_loom_rail, hip_m)
|
||||
/* u2_me_malloc(): allocate storage measured in bytes.
|
||||
*/
|
||||
void*
|
||||
u2_me_malloc(c3_w len_w);
|
||||
|
||||
/* Pork - base of frame.
|
||||
/* u2_me_free(): free storage.
|
||||
*/
|
||||
void
|
||||
u2_me_free(void* lag_v);
|
||||
|
||||
|
||||
/* Reference and arena control.
|
||||
*/
|
||||
typedef struct {
|
||||
u2_ray mut_r; // parent mat
|
||||
u2_ray rit_r; // parent rut
|
||||
c3_m hap_m; // parent hip
|
||||
} u2_loom_pork;
|
||||
# define u2_pork_mut_r(pik_r) *u2_at(pik_r, u2_loom_pork, mut_r)
|
||||
# define u2_pork_rit_r(pik_r) *u2_at(pik_r, u2_loom_pork, rit_r)
|
||||
# define u2_pork_hap_m(pik_r) *u2_at(pik_r, u2_loom_pork, hap_m)
|
||||
/* u2_me_open(): u2_yes iff a free block is available.
|
||||
*/
|
||||
u2_bean
|
||||
u2_me_open(c3_w len_w);
|
||||
|
||||
/* Floe - a solid rail allocator. Implied by `hip_m == c3__sand`.
|
||||
/* u2_me_gain(): gain and/or copy juniors.
|
||||
*/
|
||||
u2_weak
|
||||
u2_me_gain(u2_weak som);
|
||||
|
||||
/* u2_me_lose(): lose a reference.
|
||||
*/
|
||||
void
|
||||
u2_me_lose(u2_weak som);
|
||||
|
||||
/* u2_me_junior(): yes iff reference cannot be saved.
|
||||
*/
|
||||
u2_bean
|
||||
u2_me_junior(u2_noun som);
|
||||
|
||||
/* u2_me_senior(): yes iff references need not be counted.
|
||||
*/
|
||||
u2_bean
|
||||
u2_me_senior(u2_noun som);
|
||||
|
||||
/* u2_me_refs(): reference count.
|
||||
*/
|
||||
c3_w
|
||||
u2_me_refs(u2_noun som);
|
||||
|
||||
/* Atoms from proto-atoms.
|
||||
*/
|
||||
typedef struct {
|
||||
} u2_loom_floe;
|
||||
/* u2_me_slab(): create a length-bounded proto-atom.
|
||||
*/
|
||||
c3_w*
|
||||
u2_me_slab(c3_w len_w);
|
||||
|
||||
/* Soup - a liquid rail allocator.
|
||||
/* u2_me_slaq(): u2_me_slaq() with a defined blocksize.
|
||||
*/
|
||||
c3_w*
|
||||
u2_me_slaq(c3_g met_g, c3_w len_w);
|
||||
|
||||
/* u2_me_malt(): measure and finish a proto-atom.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_malt(c3_w* sal_w);
|
||||
|
||||
/* u2_me_moot(): finish a pre-measured proto-atom; dangerous.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_moot(c3_w* sal_w);
|
||||
|
||||
/* u2_me_mint(): finish a measured proto-atom.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_mint(c3_w* sal_w, c3_w len_w);
|
||||
|
||||
/* Garbage collection (for debugging only).
|
||||
*/
|
||||
# define u2_soup_free_no 28
|
||||
/* u2_me_mark(): mark for gc, returning allocated words.
|
||||
*/
|
||||
c3_w
|
||||
u2_me_mark(u2_noun som);
|
||||
|
||||
typedef struct {
|
||||
u2_ray fre_r[u2_soup_free_no]; // doubly-linked free lists
|
||||
u2_cash_slot lot_s; // modern memo cache
|
||||
#ifdef U2_PROFILE_MEMORY
|
||||
c3_w liv_w; // number of words live
|
||||
#endif
|
||||
} u2_loom_soup;
|
||||
# define u2_soup_fre_r(sop_r, x) *u2_at(sop_r, u2_loom_soup, fre_r[x])
|
||||
# define u2_soup_lot_r(sop_r) u2_aftr(sop_r, u2_loom_soup, lot_s)
|
||||
# define u2_soup_liv_w(sop_r) *u2_at(sop_r, u2_loom_soup, liv_w)
|
||||
|
||||
/* A noun box, for liquid hats. Behind pointer, addressed fwd.
|
||||
**
|
||||
** The box size is also stored at the end of the box in classic
|
||||
** bad ass malloc style. Hence a box is:
|
||||
**
|
||||
** ---
|
||||
** siz_w
|
||||
** use_w
|
||||
** user data
|
||||
** siz_w
|
||||
** ---
|
||||
**
|
||||
** Do not attempt to adjust this structure!
|
||||
/* u2_me_sweep(): sweep after gc, freeing, matching live count.
|
||||
*/
|
||||
c3_w
|
||||
u2_me_sweep(c3_w liv_w);
|
||||
|
||||
/** Generic computation.
|
||||
**/
|
||||
/* u2_me_nock_on(): produce .*(bus fol).
|
||||
*/
|
||||
typedef struct _u2_loom_rail_box {
|
||||
c3_w siz_w; // size of this box
|
||||
c3_w use_w; // reference count; free if 0
|
||||
#ifdef U2_LEAK_DEBUG
|
||||
c3_w cod_w; // allocation code
|
||||
#endif
|
||||
} u2_loom_rail_box;
|
||||
u2_noun
|
||||
u2_me_nock_on(u2_noun bus, u2_noun fol);
|
||||
|
||||
# define u2_rail_box_siz(box) *u2_at(box, u2_loom_rail_box, siz_w)
|
||||
# define u2_rail_box_use(box) *u2_at(box, u2_loom_rail_box, use_w)
|
||||
# define u2_rail_box_cod(box) *u2_at(box, u2_loom_rail_box, cod_w)
|
||||
|
||||
/* A free node. Addressed from the box.
|
||||
/* u2_me_slam_on(): produce (gat sam).
|
||||
*/
|
||||
typedef struct _u2_loom_rail_hut {
|
||||
u2_loom_rail_box b;
|
||||
u2_ray pre_r; // next on free list
|
||||
u2_ray nex_r; // next on free list
|
||||
} u2_loom_rail_hut;
|
||||
u2_noun
|
||||
u2_me_slam_on(u2_noun gat, u2_noun sam);
|
||||
|
||||
# define u2_rail_hut_siz(hut) *u2_at(hut, u2_loom_rail_hut, b.siz_w)
|
||||
# define u2_rail_hut_use(hut) *u2_at(hut, u2_loom_rail_hut, b.use_w)
|
||||
# define u2_rail_hut_pre(hut) *u2_at(hut, u2_loom_rail_hut, pre_r)
|
||||
# define u2_rail_hut_nex(hut) *u2_at(hut, u2_loom_rail_hut, nex_r)
|
||||
/* u2_me_nock_un(): produce .*(bus fol), as ++toon.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_nock_un(u2_noun bus, u2_noun fol);
|
||||
|
||||
/* u2_me_slam_un(): produce (gat sam), as ++toon.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_slam_un(u2_noun gat, u2_noun sam);
|
||||
|
||||
/* u2_me_nock_in(): produce .*(bus fol), as ++toon, in namespace.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_nock_in(u2_noun fly, u2_noun bus, u2_noun fol);
|
||||
|
||||
/* u2_me_slam_in(): produce (gat sam), as ++toon, in namespace.
|
||||
*/
|
||||
u2_noun
|
||||
u2_me_slam_in(u2_noun fly, u2_noun gat, u2_noun sam);
|
||||
|
||||
|
||||
/** Memoization.
|
||||
***
|
||||
*** The memo cache is keyed by an arbitrary symbolic function
|
||||
*** and a noun argument to that (logical) function. Functions
|
||||
*** are predefined by C-level callers, but 0 means nock.
|
||||
***
|
||||
*** The memo cache is within its road and dies when it falls.
|
||||
**/
|
||||
/* u2_me_find*(): find in memo cache.
|
||||
*/
|
||||
u2_weak u2_me_find(u2_mote, u2_noun);
|
||||
u2_weak u2_me_find_2(u2_mote, u2_noun, u2_noun);
|
||||
u2_weak u2_me_find_3(u2_mote, u2_noun, u2_noun, u2_noun);
|
||||
u2_weak u2_me_find_4(u2_mote, u2_noun, u2_noun, u2_noun, u2_noun);
|
||||
|
||||
/* u2_me_save*(): save in memo cache.
|
||||
*/
|
||||
u2_weak u2_me_save(u2_mote, u2_noun, u2_noun);
|
||||
u2_weak u2_me_save_2(u2_mote, u2_noun, u2_noun, u2_noun);
|
||||
u2_weak u2_me_save_3(u2_mote, u2_noun, u2_noun, u2_noun, u2_noun);
|
||||
u2_weak u2_me_save_4
|
||||
(u2_mote, u2_noun, u2_noun, u2_noun, u2_noun, u2_noun);
|
||||
|
||||
/* u2_me_uniq(): uniquify with memo cache.
|
||||
*/
|
||||
u2_weak u2_me_u
|
||||
/* u2_rl_find():
|
||||
**
|
||||
** Cache search for function (0 means nock) and sample.
|
||||
*/
|
||||
u2_weak // transfer
|
||||
u2_rl_find(u2_ray ral_r,
|
||||
u2_mote fun_m,
|
||||
u2_noun sam); // retain
|
||||
|
||||
/* u2_rl_save():
|
||||
**
|
||||
** Cache store for function (0 means nock), sample and product.
|
||||
*/
|
||||
u2_weak // transfer
|
||||
u2_rl_save(u2_ray ral_r,
|
||||
u2_mote fun_m, // retain
|
||||
u2_noun sam, // retain
|
||||
u2_noun pro); // transfer
|
||||
|
||||
/* u2_rl_uniq():
|
||||
**
|
||||
** Use cache to render object unique.
|
||||
*/
|
||||
u2_noun // produce
|
||||
u2_rl_uniq(u2_ray ral_r,
|
||||
u2_noun som); // submit
|
||||
|
||||
/* u2_rl_find_cell(): as u2_rl_find(), for `sam=[a b]`.
|
||||
** u2_rl_find_trel(): as u2_rl_find(), for `sam=[a b c]`.
|
||||
** u2_rl_find_qual(): as u2_rl_find(), for `sam=[a b d]`.
|
||||
** u2_rl_find_quil(): as u2_rl_find(), for `sam=[a b c d e]`.
|
||||
**
|
||||
** Extend as needed...
|
||||
*/
|
||||
u2_weak // transfer
|
||||
u2_rl_find_cell(u2_ray, u2_mote, u2_noun, // retain
|
||||
u2_noun); // retain
|
||||
u2_weak // transfer
|
||||
u2_rl_find_trel(u2_ray, u2_mote, u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun); // retain
|
||||
u2_weak // transfer
|
||||
u2_rl_find_qual(u2_ray, u2_mote, u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun); // retain
|
||||
u2_weak // transfer
|
||||
u2_rl_find_quil(u2_ray, u2_mote, u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun); // retain
|
||||
|
||||
/* u2_rl_save_cell(): as u2_rl_save(), for `sam=[a b]`.
|
||||
** u2_rl_save_trel(): as u2_rl_save(), for `sam=[a b c]`.
|
||||
** u2_rl_save_qual(): as u2_rl_save(), for `sam=[a b c d]`.
|
||||
** u2_rl_save_quil(): as u2_rl_save(), for `sam=[a b c d e]`.
|
||||
**
|
||||
** Extended
|
||||
*/
|
||||
u2_weak // transfer
|
||||
u2_rl_save_cell(u2_ray, u2_mote, u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun); // transfer
|
||||
|
||||
u2_weak // transfer
|
||||
u2_rl_save_trel(u2_ray, u2_mote, u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun); // transfer
|
||||
|
||||
u2_weak // transfer
|
||||
u2_rl_save_qual(u2_ray, u2_mote, u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun); // transfer
|
||||
|
||||
u2_weak // transfer
|
||||
u2_rl_save_quil(u2_ray, u2_mote, u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun, // retain
|
||||
u2_noun); // transfer
|
||||
|
||||
# define u2_rail_box(som) \
|
||||
( u2_fly_is_cat(som) \
|
||||
? 0 \
|
||||
: (u2_dog_a(som) - c3_wiseof(u2_loom_rail_box)) )
|
||||
|
||||
/** Abbreviations.
|
||||
**/
|
||||
@ -217,172 +388,6 @@
|
||||
|
||||
/** Functions.
|
||||
**/
|
||||
/** Miscellaneous and interesting.
|
||||
**/
|
||||
/* u2_rl_boot():
|
||||
**
|
||||
** Create an empty rail in an empty loom, with memory model `hip`.
|
||||
** See u2_rl_leap() for storage policies.
|
||||
*/
|
||||
u2_ray
|
||||
u2_rl_boot(c3_m hip_m);
|
||||
|
||||
/* u2_rl_clear():
|
||||
**
|
||||
** Yes iff [lef] does not point to any word >= [net]
|
||||
** and < [bat].
|
||||
*/
|
||||
u2_bean
|
||||
u2_rl_clear(u2_noun lef,
|
||||
u2_ray net_r,
|
||||
u2_ray bat_r);
|
||||
|
||||
/* u2_rl_init():
|
||||
**
|
||||
** Install an empty rail within `hat_r` and `mat_r` in the loom,
|
||||
** with memory model `hip`.
|
||||
**
|
||||
** Returns ray to rail, which always equalls the passed `mat_r`.
|
||||
*/
|
||||
u2_ray
|
||||
u2_rl_init(c3_m hip_m,
|
||||
u2_ray hat_r,
|
||||
u2_ray mat_r);
|
||||
|
||||
/* u2_rl_dump():
|
||||
**
|
||||
** Print memory structure for benefit of archeologists.
|
||||
*/
|
||||
void
|
||||
u2_rl_dump(u2_ray ral_r);
|
||||
|
||||
/* u2_rl_drain():
|
||||
**
|
||||
** Clear the memo cache (soup).
|
||||
*/
|
||||
void
|
||||
u2_rl_drain(u2_ray ral_r);
|
||||
|
||||
/* u2_rl_fall():
|
||||
**
|
||||
** Reverse the beams backward, restoring the old frame.
|
||||
*/
|
||||
void
|
||||
u2_rl_fall(u2_ray ral_r);
|
||||
|
||||
/* u2_rl_fall_part():
|
||||
**
|
||||
** Fall on `ral`, also releasing the partition `aux`.
|
||||
*/
|
||||
void
|
||||
u2_rl_fall_part(u2_ray ral_r,
|
||||
u2_ray aux_r);
|
||||
|
||||
/* u2_rl_flog():
|
||||
**
|
||||
** Release the can, setting cap to mat.
|
||||
*/
|
||||
void
|
||||
u2_rl_flog(u2_ray ral_r);
|
||||
|
||||
/* u2_rl_gain():
|
||||
**
|
||||
** Gain a reference to `som`, returning it.
|
||||
*/
|
||||
u2_weak // transfer
|
||||
u2_rl_gain(u2_ray ral_r,
|
||||
u2_weak som); // retain
|
||||
|
||||
/* u2_rl_free():
|
||||
**
|
||||
** Free storage allocated by u2_rl_malloc().
|
||||
*/
|
||||
void
|
||||
u2_rl_free(u2_ray ral_r,
|
||||
void* lag_v);
|
||||
|
||||
/* u2_rl_ok():
|
||||
**
|
||||
** Ensure that all reference counts are valid in `som`.
|
||||
*/
|
||||
void
|
||||
u2_rl_ok(u2_ray ral_r,
|
||||
u2_noun som); // retain
|
||||
|
||||
/* u2_rl_junior():
|
||||
**
|
||||
** Yes iff `dus` is junior in `ral` - ie, must be copied
|
||||
** to be referenced on the hat.
|
||||
*/
|
||||
u2_bean
|
||||
u2_rl_junior(u2_ray ral_r,
|
||||
u2_noun dus); // retain
|
||||
|
||||
/* u2_rl_leap():
|
||||
**
|
||||
** Reverse the beams forward, with memory model `hip`.
|
||||
** Memory models at present:
|
||||
**
|
||||
** c3__sand solid, no boxes or reference counts
|
||||
** c3__rock liquid, boxes, reference-counted heap
|
||||
**
|
||||
** Returns u2_yes on success.
|
||||
*/
|
||||
u2_bean
|
||||
u2_rl_leap(u2_ray ral_r,
|
||||
c3_m hip_m);
|
||||
|
||||
/* u2_rl_leap_part():
|
||||
**
|
||||
** Reverse and split rail, inserting partition of size `num/dem`
|
||||
** plus `tip`.
|
||||
**
|
||||
** Returns partition rail, `aux_r`.
|
||||
*/
|
||||
u2_ray
|
||||
u2_rl_leap_part(u2_ray ral_r,
|
||||
c3_m hop_m,
|
||||
c3_w num_w,
|
||||
c3_w dem_w,
|
||||
c3_w tip_w);
|
||||
|
||||
/* u2_rl_lose():
|
||||
**
|
||||
** Lose a reference to `som`. Free it if refcount == 0.
|
||||
*/
|
||||
void
|
||||
u2_rl_lose(u2_ray ral_r,
|
||||
u2_weak som); // transfer
|
||||
|
||||
/* u2_rl_gc_mark_noun():
|
||||
**
|
||||
** Mark a noun for gc. Return allocated words.
|
||||
*/
|
||||
c3_w
|
||||
u2_rl_gc_mark_noun(u2_ray ral_r,
|
||||
u2_noun som);
|
||||
|
||||
/* u2_rl_gc_mark_ptr():
|
||||
**
|
||||
** Mark a pointer allocated with ralloc. Return allocated words.
|
||||
*/
|
||||
c3_w
|
||||
u2_rl_gc_mark_ptr(u2_ray ral_r,
|
||||
u2_ray ptr_r);
|
||||
|
||||
/* u2_rl_gc_mark():
|
||||
**
|
||||
** Mark a rail (mainly memo cache). Return allocated words.
|
||||
*/
|
||||
c3_w
|
||||
u2_rl_gc_mark(u2_ray ral_r);
|
||||
|
||||
/* u2_rl_gc_sweep():
|
||||
**
|
||||
** Sweep memory, freeing unused blocks. Match live, save leaked.
|
||||
*/
|
||||
c3_w
|
||||
u2_rl_gc_sweep(u2_ray ral_r, c3_w sav_w);
|
||||
|
||||
/* u2_rl_malloc():
|
||||
**
|
||||
@ -392,31 +397,6 @@
|
||||
u2_rl_malloc(u2_ray ral_r,
|
||||
c3_w sib_w);
|
||||
|
||||
/* u2_rl_malt():
|
||||
**
|
||||
** Initialize slab `sal` as an atom, internally measured.
|
||||
*/
|
||||
u2_atom // transfer
|
||||
u2_rl_malt(u2_rail ral_r,
|
||||
u2_ray sal_r);
|
||||
|
||||
/* u2_rl_mint():
|
||||
**
|
||||
** Initialize slab `sal` as an atom, externally measured.
|
||||
*/
|
||||
u2_atom // transfer
|
||||
u2_rl_mint(u2_rail ral_r,
|
||||
u2_ray sal_r,
|
||||
c3_w len_w);
|
||||
|
||||
/* u2_rl_moot():
|
||||
**
|
||||
** Initialize slab `sal` as an atom, originally measured.
|
||||
*/
|
||||
u2_atom // transfer
|
||||
u2_rl_moot(u2_rail ral_r,
|
||||
u2_ray sal_r);
|
||||
|
||||
/* u2_rl_open():
|
||||
**
|
||||
** Yes iff [a] more words remain in the pad.
|
||||
@ -450,23 +430,6 @@
|
||||
u2_rl_senior(u2_ray ral_r,
|
||||
u2_noun dus); // retain
|
||||
|
||||
/* u2_rl_slab():
|
||||
**
|
||||
** Create a blank atomic slab of `len` words.
|
||||
*/
|
||||
u2_ray
|
||||
u2_rl_slab(u2_rail ral_r,
|
||||
c3_w len_w);
|
||||
|
||||
/* u2_rl_slaq():
|
||||
**
|
||||
** Create a blank atomic slab of `len` bloqs of size `met`.
|
||||
*/
|
||||
u2_ray
|
||||
u2_rl_slaq(u2_wire wir_r,
|
||||
c3_g met_g,
|
||||
c3_w len_w);
|
||||
|
||||
/* u2_rl_refs():
|
||||
**
|
||||
** Return the reference count of (som). For debugging, etc.
|
||||
|
Loading…
Reference in New Issue
Block a user