diff --git a/g/a.c b/g/a.c index 67f4cd67a..5dc79988b 100644 --- a/g/a.c +++ b/g/a.c @@ -36,6 +36,8 @@ _box_make(void* box_v, c3_w siz_w, c3_w use_w) u3_cs_box* box_u = box_v; c3_w* box_w = box_v; + c3_assert(siz_w >= u3_cc_minimum); + box_w[0] = siz_w; box_w[siz_w - 1] = siz_w; box_u->use_w = use_w; @@ -55,6 +57,7 @@ void _box_attach(u3_cs_box* box_u) { c3_assert(box_u->siz_w >= (1 + c3_wiseof(u3_cs_fbox))); + c3_assert(0 != u3of(u3_cs_fbox, box_u)); #if 0 // For debugging, fill the box with beef. @@ -70,17 +73,17 @@ _box_attach(u3_cs_box* box_u) u3R->all.fre_w += box_u->siz_w; { - c3_w sel_w = _box_slot(box_u->siz_w); - u3_cs_fbox* fre_u = (void *)box_u; - u3_cs_fbox** pfr_u = &u3R->all.fre_u[sel_w]; - u3_cs_fbox* nex_u = *pfr_u; + c3_w sel_w = _box_slot(box_u->siz_w); + u3p(u3_cs_fbox) fre_p = u3of(u3_cs_fbox, box_u); + u3p(u3_cs_fbox)* pfr_p = &u3R->all.fre_p[sel_w]; + u3p(u3_cs_fbox) nex_p = *pfr_p; - fre_u->pre_u = 0; - fre_u->nex_u = nex_u; - if ( fre_u->nex_u ) { - fre_u->nex_u->pre_u = fre_u; + u3to(u3_cs_fbox, fre_p)->pre_p = 0; + u3to(u3_cs_fbox, fre_p)->nex_p = nex_p; + if ( u3to(u3_cs_fbox, fre_p)->nex_p ) { + u3to(u3_cs_fbox, u3to(u3_cs_fbox, fre_p)->nex_p)->pre_p = fre_p; } - (*pfr_u) = fre_u; + (*pfr_p) = fre_p; } } @@ -89,25 +92,25 @@ _box_attach(u3_cs_box* box_u) void _box_detach(u3_cs_box* box_u) { - u3_cs_fbox* fre_u = (void*) box_u; - u3_cs_fbox* pre_u = fre_u->pre_u; - u3_cs_fbox* nex_u = fre_u->nex_u; + u3p(u3_cs_fbox) fre_p = u3of(u3_cs_fbox, box_u); + u3p(u3_cs_fbox) pre_p = u3to(u3_cs_fbox, fre_p)->pre_p; + u3p(u3_cs_fbox) nex_p = u3to(u3_cs_fbox, fre_p)->nex_p; u3R->all.fre_w -= box_u->siz_w; - if ( nex_u ) { - c3_assert(nex_u->pre_u == fre_u); - nex_u->pre_u = pre_u; + if ( nex_p ) { + c3_assert(u3to(u3_cs_fbox, nex_p)->pre_p == fre_p); + u3to(u3_cs_fbox, nex_p)->pre_p = pre_p; } - if ( pre_u ) { - c3_assert(pre_u->nex_u == fre_u); - pre_u->nex_u = nex_u; + if ( pre_p ) { + c3_assert(u3to(u3_cs_fbox, pre_p)->nex_p == fre_p); + u3to(u3_cs_fbox, pre_p)->nex_p = nex_p; } else { c3_w sel_w = _box_slot(box_u->siz_w); - c3_assert(fre_u == u3R->all.fre_u[sel_w]); - u3R->all.fre_u[sel_w] = nex_u; + c3_assert(fre_p == u3R->all.fre_p[sel_w]); + u3R->all.fre_p[sel_w] = nex_p; } } @@ -157,6 +160,7 @@ _me_road_all_cap(c3_w len_w) } #endif +#if 0 /* u3_ca_sane(): check allocator sanity. */ void @@ -182,6 +186,7 @@ u3_ca_sane(void) } } } +#endif /* _ca_walloc(): u3_ca_walloc() internals. */ @@ -197,11 +202,12 @@ _ca_walloc(c3_w len_w) sel_w += 1; } + // fprintf(stderr, "walloc %d: *pfr_p %x\n", len_w, u3R->all.fre_p[sel_w]); while ( 1 ) { - u3_cs_fbox** pfr_u = &u3R->all.fre_u[sel_w]; + u3p(u3_cs_fbox) *pfr_p = &u3R->all.fre_p[sel_w]; while ( 1 ) { - if ( 0 == *pfr_u ) { + if ( 0 == *pfr_p ) { if ( sel_w < (u3_cc_fbox_no - 1) ) { sel_w += 1; break; @@ -213,34 +219,39 @@ _ca_walloc(c3_w len_w) } } else { - if ( siz_w > (*pfr_u)->box_u.siz_w ) { + if ( siz_w > u3to(u3_cs_fbox, *pfr_p)->box_u.siz_w ) { /* This free block is too small. Continue searching. */ - pfr_u = &((*pfr_u)->nex_u); + pfr_p = &(u3to(u3_cs_fbox, *pfr_p)->nex_p); continue; } else { - u3_cs_box* box_u = &((*pfr_u)->box_u); + u3_cs_box* box_u = &(u3to(u3_cs_fbox, *pfr_p)->box_u); /* We have found a free block of adequate size. Remove it ** from the free list. */ { { - c3_assert((0 == (*pfr_u)->pre_u) || - (*pfr_u)->pre_u->nex_u == (*pfr_u)); - c3_assert((0 == (*pfr_u)->nex_u) || - (*pfr_u)->nex_u->pre_u == (*pfr_u)); + c3_assert((0 == u3to(u3_cs_fbox, *pfr_p)->pre_p) || + (u3to(u3_cs_fbox, u3to(u3_cs_fbox, *pfr_p)->pre_p)->nex_p + == (*pfr_p))); + + c3_assert((0 == u3to(u3_cs_fbox, *pfr_p)->nex_p) || + (u3to(u3_cs_fbox, u3to(u3_cs_fbox, *pfr_p)->nex_p)->pre_p + == (*pfr_p))); } - if ( 0 != (*pfr_u)->nex_u ) { - (*pfr_u)->nex_u->pre_u = (*pfr_u)->pre_u; + + if ( 0 != u3to(u3_cs_fbox, *pfr_p)->nex_p ) { + u3to(u3_cs_fbox, u3to(u3_cs_fbox, *pfr_p)->nex_p)->pre_p = + u3to(u3_cs_fbox, *pfr_p)->pre_p; } - *pfr_u = (*pfr_u)->nex_u; + *pfr_p = u3to(u3_cs_fbox, *pfr_p)->nex_p; } /* If we can chop off another block, do it. */ - if ( (siz_w + c3_wiseof(u3_cs_fbox) + 1) <= box_u->siz_w ) { + if ( (siz_w + u3_cc_minimum) <= box_u->siz_w ) { /* Split the block. */ c3_w* box_w = ((c3_w *)(void *)box_u); @@ -1143,11 +1154,13 @@ u3_ca_sweep(c3_c* cap_c) : (u3R->rut_w - u3R->hat_w); for ( i_w = 0; i_w < u3_cc_fbox_no; i_w++ ) { - u3_cs_fbox* fre_u = u3R->all.fre_u[i_w]; - - while ( fre_u ) { + u3p(u3_cs_fbox) fre_p = u3R->all.fre_p[i_w]; + + while ( fre_p ) { + u3_cs_fbox* fre_u = u3to(u3_cs_fbox, fre_p); + fre_w += fre_u->box_u.siz_w; - fre_u = fre_u->nex_u; + fre_p = fre_u->nex_p; } } neg_w = (end_w - fre_w); diff --git a/g/e.c b/g/e.c index 710c8a9c0..15e1a4e5a 100644 --- a/g/e.c +++ b/g/e.c @@ -78,35 +78,32 @@ u3_ce_check(c3_c* cap_c) c3_i u3_ce_fault(void* adr_v, c3_i ser_i) { - if ( ser_i ) { - c3_w* adr_w = (c3_w*) adr_v; + c3_w* adr_w = (c3_w*) adr_v; - if ( (adr_w < u3_Loom) || (adr_w > (u3_Loom + u3_cc_words)) ) { - fprintf(stderr, "address %p out of loom!\r\n", adr_v); + if ( (adr_w < u3_Loom) || (adr_w > (u3_Loom + u3_cc_words)) ) { + fprintf(stderr, "address %p out of loom!\r\n", adr_v); + c3_assert(0); + return 0; + } + else { + c3_w off_w = (adr_w - u3_Loom); + c3_w pag_w = off_w >> u3_cc_page; + c3_w blk_w = (pag_w >> 5); + c3_w bit_w = (pag_w & 31); + + // printf("dirty page %d\r\n", pag_w); + c3_assert(0 == (u3P.dit_w[blk_w] & (1 << bit_w))); + u3P.dit_w[blk_w] |= (1 << bit_w); + + if ( -1 == mprotect((void *)(u3_Loom + (pag_w << u3_cc_page)), + (1 << (u3_cc_page + 2)), + (PROT_READ | PROT_WRITE)) ) + { + perror("mprotect"); c3_assert(0); return 0; } - else { - c3_w off_w = (adr_w - u3_Loom); - c3_w pag_w = off_w >> u3_cc_page; - c3_w blk_w = (pag_w >> 5); - c3_w bit_w = (pag_w & 31); - - // printf("dirty page %d\r\n", pag_w); - c3_assert(0 == (u3P.dit_w[blk_w] & (1 << bit_w))); - u3P.dit_w[blk_w] |= (1 << bit_w); - - if ( -1 == mprotect((void *)(u3_Loom + (pag_w << u3_cc_page)), - (1 << (u3_cc_page + 2)), - (PROT_READ | PROT_WRITE)) ) - { - perror("mprotect"); - c3_assert(0); - return 0; - } - } } - return 1; } /* _ce_image_open(): open or create image. diff --git a/g/m.c b/g/m.c index 72ce45525..5caed27ec 100644 --- a/g/m.c +++ b/g/m.c @@ -368,13 +368,17 @@ void u3_cm_boot(c3_o nuu_o, c3_o bug_o) { if ( u3_yes == nuu_o ) { - u3H = (void *)_boot_north(u3_Loom, c3_wiseof(u3_cs_home), u3_cc_words); + u3H = (void *)_boot_north(u3_Loom + 1, + c3_wiseof(u3_cs_home), + u3_cc_words - 1); u3R = &u3H->rod_u; _boot_parts(); } else { - u3H = (void *)_find_north(u3_Loom, c3_wiseof(u3_cs_home), u3_cc_words); + u3H = (void *)_find_north(u3_Loom + 1, + c3_wiseof(u3_cs_home), + u3_cc_words - 1); u3R = &u3H->rod_u; } @@ -393,6 +397,7 @@ u3_cm_clear(void) u3_ca_lose(u3R->jed.das); } +#if 0 void u3_cm_dump(void) { @@ -433,6 +438,7 @@ u3_cm_dump(void) fprintf(stderr, "second count: %x\n", mem_w); } } +#endif c3_w Exit; diff --git a/include/g/h.h b/include/g/h.h index a25964d9c..1e77eb022 100644 --- a/include/g/h.h +++ b/include/g/h.h @@ -2,12 +2,10 @@ ** ** This file is in the public domain. */ - /** Functions. *** *** Needs: delete and merge functions; clock reclamation function. **/ - /* u3_ch_new(): create hashtable. */ u3_ch_root* diff --git a/include/n/noun.h b/include/n/noun.h index 2b69e5cc1..e89bedef8 100644 --- a/include/n/noun.h +++ b/include/n/noun.h @@ -4,15 +4,20 @@ */ /** Data structures. **/ + /* u3_post: pointer offset into u3_Loom; _p suffix; declare as u3p(). + */ + typedef c3_w u3_post; +# define u3p(type) u3_post + /* u3_noun: tagged pointer. ** ** If bit 31 is 0, a u3_noun is a direct 31-bit atom ("cat"). ** If bit 31 is 1 and bit 30 0, an indirect atom ("pug"). ** If bit 31 is 1 and bit 30 1, an indirect cell ("pom"). ** - ** Bits 0-29 are a word offset against u3_Loom. + ** Bits 0-29 are a word offset against u3_Loom (u3_post). */ - typedef c3_w u3_noun; + typedef c3_w u3_noun; /* u3_none - out-of-band noun. */ diff --git a/include/n/road.h b/include/n/road.h index e40cecfbb..880cd4104 100644 --- a/include/n/road.h +++ b/include/n/road.h @@ -41,12 +41,14 @@ ** */ typedef struct _u3_cs_fbox { - u3_cs_box box_u; - struct _u3_cs_fbox* pre_u; - struct _u3_cs_fbox* nex_u; + u3_cs_box box_u; + u3p(struct _u3_cs_fbox) pre_p; + u3p(struct _u3_cs_fbox) nex_p; } u3_cs_fbox; -# define u3_cc_minimum (1 + c3_wiseof(u3_cs_fbox)) +# define u3_cc_minimum 6 +# define u3_cc_fbox_no 28 + /* u3_cs_road: contiguous allocation and execution context. ** @@ -117,61 +119,58 @@ ** u3H, the top-level road. */ typedef struct _u3_cs_road { - struct _u3_cs_road* par_u; // parent road + struct _u3_cs_road* par_u; // parent road - struct _u3_cs_road* kid_u; // child road list - struct _u3_cs_road* nex_u; // sibling road - struct _u3_cs_road* now_u; // current road pointer + struct _u3_cs_road* kid_u; // child road list + struct _u3_cs_road* nex_u; // sibling road + struct _u3_cs_road* now_u; // current road pointer - 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 - c3_w* ear_w; // original cap if kid is live -#if 0 - c3_w* gar_w; // bottom of guard region (future) - c3_w* rag_w; // top of guard region (future) - c3_w pad_w[4]; // future interesting info -#endif + 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 + c3_w* ear_w; // original cap if kid is live - struct { // escape buffer + c3_w fut_w[32]; // futureproof buffer + + struct { // escape buffer union { jmp_buf buf; - c3_w buf_w[256]; // futureproofing + c3_w buf_w[256]; // futureproofing }; } esc; - struct { // miscellaneous config - c3_w fag_w; // flag bits - } how; // + struct { // miscellaneous config + c3_w fag_w; // flag bits + } how; // - struct { // allocation pools - u3_cs_fbox* fre_u[u3_cc_fbox_no]; // heap by node size log - c3_w fre_w; // number of free words + struct { // allocation pools + u3p(u3_cs_fbox) fre_p[u3_cc_fbox_no]; // heap by node size log + c3_w fre_w; // number of free words } all; - struct { // jet dashboard - u3_ch_root* har_u; // jet index (old style) - u3_noun das; // dashboard (new style) + struct { // jet dashboard + u3_ch_root* har_u; // jet index (old style) + u3_noun das; // dashboard (new style) } jed; - struct { // namespace - u3_noun flu; // (list $+(* (unit))), inward + struct { // namespace + u3_noun flu; // (list $+(* (unit))), inward } ski; - struct { // trace stack - u3_noun tax; // (list ,*) - u3_noun mer; // emergency buffer to release + struct { // trace stack + u3_noun tax; // (list ,*) + u3_noun mer; // emergency buffer to release } bug; - struct { // profile stack - c3_d nox_d; // nock steps - u3_noun don; // ++path - u3_noun day; // profile data, ++doss + struct { // profile stack + c3_d nox_d; // nock steps + u3_noun don; // ++path + u3_noun day; // profile data, ++doss } pro; - struct { // memoization - u3_ch_root* har_u; // (map (pair term noun) noun) + struct { // memoization + u3_ch_root* har_u; // (map (pair term noun) noun) } cax; } u3_cs_road; typedef u3_cs_road u3_road; @@ -179,10 +178,10 @@ /** Flags. **/ enum u3_cs_flag { - u3_cs_flag_debug = 0x1, // debug memory - u3_cs_flag_gc = 0x2, // garbage collect once - u3_cs_flag_sand = 0x4, // sand mode, bump allocation - u3_cs_flag_die = 0x8 // process was asked to exit + u3_cs_flag_debug = 0x1, // debug memory + u3_cs_flag_gc = 0x2, // garbage collect once + u3_cs_flag_sand = 0x4, // sand mode, bump allocation + u3_cs_flag_die = 0x8 // process was asked to exit }; /** Macros. @@ -191,6 +190,7 @@ # define u3_co_outa(p) (((c3_w*)(void*)(p)) - u3_Loom) # define u3to(type, x) ((type *) u3_co_into(x)) +# define u3of(type, x) (u3_co_outa((type *)x)) # define u3_co_is_north(r) ((r->cap_w > r->hat_w) ? u3_yes : u3_no) # define u3_co_is_south(r) ((u3_so(u3_co_is_north(r))) ? u3_no : u3_yes) diff --git a/include/n/tune.h b/include/n/tune.h index 2fbd16926..c108107b4 100644 --- a/include/n/tune.h +++ b/include/n/tune.h @@ -4,8 +4,6 @@ */ /** Tuning and configuration. **/ -# define u3_cc_fbox_no 28 - # undef U3_MEMORY_DEBUG # ifdef U3_MEMORY_DEBUG # define u3_leak_on(x) (u3_Code = x)