diff --git a/pkg/noun/allocate.c b/pkg/noun/allocate.c index 8ca5085397..829356a96a 100644 --- a/pkg/noun/allocate.c +++ b/pkg/noun/allocate.c @@ -2005,9 +2005,8 @@ u3a_maid(FILE* fil_u, c3_c* cap_c, c3_w wor_w) /* _ca_print_memory(): un-captioned u3a_print_memory(). */ static void -_ca_print_memory(FILE* fil_u, c3_w wor_w) +_ca_print_memory(FILE* fil_u, c3_w byt_w) { - c3_w byt_w = (wor_w * 4); c3_w gib_w = (byt_w / 1000000000); c3_w mib_w = (byt_w % 1000000000) / 1000000; c3_w kib_w = (byt_w % 1000000) / 1000; @@ -2028,43 +2027,55 @@ _ca_print_memory(FILE* fil_u, c3_w wor_w) } } +/* u3a_quac_free: free quac memory. +*/ +void +u3a_quac_free(u3m_quac* qua_u) +{ + c3_w i_w = 0; + while ( qua_u->qua_u[i_w] != NULL ) { + u3a_quac_free(qua_u->qua_u[i_w]); + i_w++; + } + c3_free(qua_u->nam_c); + c3_free(qua_u->qua_u); + c3_free(qua_u); +} + /* u3a_prof(): mark/measure/print memory profile. RETAIN. */ -c3_w -u3a_prof(FILE* fil_u, c3_w den_w, u3_noun mas) +u3m_quac* +u3a_prof(FILE* fil_u, u3_noun mas) { - c3_w tot_w = 0; + u3m_quac* pro_u = c3_calloc(sizeof(*pro_u)); u3_noun h_mas, t_mas; if ( c3n == u3r_cell(mas, &h_mas, &t_mas) ) { - fprintf(fil_u, "%.*smistyped mass\r\n", den_w, ""); - return tot_w; + fprintf(fil_u, "mistyped mass\r\n"); + c3_free(pro_u); + return NULL; } - else if ( _(u3du(h_mas)) ) { - fprintf(fil_u, "%.*smistyped mass head\r\n", den_w, ""); + else if ( c3y == u3du(h_mas) ) { + fprintf(fil_u, "mistyped mass head\r\n"); { c3_c* lab_c = u3m_pretty(h_mas); fprintf(fil_u, "h_mas: %s", lab_c); c3_free(lab_c); } - return tot_w; + c3_free(pro_u); + return NULL; } else { - { - c3_c* lab_c = u3m_pretty(h_mas); - fprintf(fil_u, "%*s%s: ", den_w, "", lab_c); - c3_free(lab_c); - } u3_noun it_mas, tt_mas; if ( c3n == u3r_cell(t_mas, &it_mas, &tt_mas) ) { - fprintf(fil_u, "%*smistyped mass tail\r\n", den_w, ""); - return tot_w; + fprintf(fil_u, "mistyped mass tail\r\n"); + c3_free(pro_u); + return NULL; } else if ( c3y == it_mas ) { - tot_w += u3a_mark_noun(tt_mas); - _ca_print_memory(fil_u, tot_w); + c3_w siz_w = u3a_mark_noun(tt_mas); #if 1 /* The basic issue here is that tt_mas is included in .sac @@ -2075,7 +2086,7 @@ u3a_prof(FILE* fil_u, c3_w den_w, u3_noun mas) * * see u3a_mark_ptr(). */ - if ( _(u3a_is_dog(tt_mas)) ) { + if ( c3y == u3a_is_dog(tt_mas) ) { u3a_box* box_u = u3a_botox(u3a_to_ptr(tt_mas)); #ifdef U3_MEMORY_DEBUG if ( 1 == box_u->eus_w ) { @@ -2094,45 +2105,131 @@ u3a_prof(FILE* fil_u, c3_w den_w, u3_noun mas) #endif } #endif + pro_u->nam_c = u3r_string(h_mas); + pro_u->siz_w = siz_w*4; + pro_u->qua_u = NULL; + return pro_u; - return tot_w; } else if ( c3n == it_mas ) { - fprintf(fil_u, "\r\n"); - - while ( _(u3du(tt_mas)) ) { - tot_w += u3a_prof(fil_u, den_w+2, u3h(tt_mas)); + pro_u->qua_u = c3_malloc(sizeof(pro_u->qua_u)); + c3_w i_w = 0; + c3_t bad_t = 0; + while ( c3y == u3du(tt_mas) ) { + u3m_quac* new_u = u3a_prof(fil_u, u3h(tt_mas)); + if ( NULL == new_u ) { + bad_t = 1; + } else { + pro_u->qua_u = c3_realloc(pro_u->qua_u, (i_w + 2) * sizeof(pro_u->qua_u)); + pro_u->siz_w += new_u->siz_w; + pro_u->qua_u[i_w] = new_u; + } tt_mas = u3t(tt_mas); + i_w++; } + pro_u->qua_u[i_w] = NULL; - fprintf(fil_u, "%*s--", den_w, ""); - _ca_print_memory(fil_u, tot_w); - - return tot_w; - + if ( bad_t ) { + i_w = 0; + while ( pro_u->qua_u[i_w] != NULL ) { + u3a_quac_free(pro_u->qua_u[i_w]); + i_w++; + } + c3_free(pro_u->qua_u); + c3_free(pro_u); + return NULL; + } else { + pro_u->nam_c = u3r_string(h_mas); + return pro_u; + } } else { - fprintf(fil_u, "%*smistyped (strange) mass tail\r\n", den_w, ""); - return tot_w; + fprintf(fil_u, "mistyped (strange) mass tail\r\n"); + c3_free(pro_u); + return NULL; + } + } +} + + +/* u3a_print_quac: print a memory report. +*/ + +void +u3a_print_quac(FILE* fil_u, c3_w den_w, u3m_quac* mas_u) +{ + u3_assert( 0 != fil_u ); + + if ( mas_u->siz_w ) { + fprintf(fil_u, "%*s%s: ", den_w, "", mas_u->nam_c); + + if ( mas_u->qua_u == NULL ) { + _ca_print_memory(fil_u, mas_u->siz_w); + } else { + fprintf(fil_u, "\r\n"); + c3_w i_w = 0; + while ( mas_u->qua_u[i_w] != NULL ) { + u3a_print_quac(fil_u, den_w+2, mas_u->qua_u[i_w]); + i_w++; + } + fprintf(fil_u, "%*s--", den_w, ""); + _ca_print_memory(fil_u, mas_u->siz_w); } } } /* u3a_mark_road(): mark ad-hoc persistent road structures. */ -c3_w -u3a_mark_road(FILE* fil_u) -{ - c3_w tot_w = 0; - tot_w += u3a_maid(fil_u, " namespace", u3a_mark_noun(u3R->ski.gul)); - tot_w += u3a_maid(fil_u, " trace stack", u3a_mark_noun(u3R->bug.tax)); - tot_w += u3a_maid(fil_u, " trace buffer", u3a_mark_noun(u3R->bug.mer)); - tot_w += u3a_maid(fil_u, " profile batteries", u3a_mark_noun(u3R->pro.don)); - tot_w += u3a_maid(fil_u, " profile doss", u3a_mark_noun(u3R->pro.day)); - tot_w += u3a_maid(fil_u, " new profile trace", u3a_mark_noun(u3R->pro.trace)); - tot_w += u3a_maid(fil_u, " transient memoization cache", u3h_mark(u3R->cax.har_p)); - tot_w += u3a_maid(fil_u, " persistent memoization cache", u3h_mark(u3R->cax.per_p)); - return u3a_maid(fil_u, "total road stuff", tot_w); +u3m_quac* +u3a_mark_road() +{ + u3m_quac** qua_u = c3_malloc(sizeof(*qua_u) * 9); + + qua_u[0] = c3_calloc(sizeof(*qua_u[0])); + qua_u[0]->nam_c = strdup("namespace"); + qua_u[0]->siz_w = u3a_mark_noun(u3R->ski.gul) * 4; + + qua_u[1] = c3_calloc(sizeof(*qua_u[1])); + qua_u[1]->nam_c = strdup("trace stack"); + qua_u[1]->siz_w = u3a_mark_noun(u3R->bug.tax) * 4; + + qua_u[2] = c3_calloc(sizeof(*qua_u[2])); + qua_u[2]->nam_c = strdup("trace buffer"); + qua_u[2]->siz_w = u3a_mark_noun(u3R->bug.mer) * 4; + + qua_u[3] = c3_calloc(sizeof(*qua_u[3])); + qua_u[3]->nam_c = strdup("profile batteries"); + qua_u[3]->siz_w = u3a_mark_noun(u3R->pro.don) * 4; + + qua_u[4] = c3_calloc(sizeof(*qua_u[4])); + qua_u[4]->nam_c = strdup("profile doss"); + qua_u[4]->siz_w = u3a_mark_noun(u3R->pro.day) * 4; + + qua_u[5] = c3_calloc(sizeof(*qua_u[5])); + qua_u[5]->nam_c = strdup("new profile trace"); + qua_u[5]->siz_w = u3a_mark_noun(u3R->pro.trace) * 4; + + qua_u[6] = c3_calloc(sizeof(*qua_u[6])); + qua_u[6]->nam_c = strdup("transient memoization cache"); + qua_u[6]->siz_w = u3h_mark(u3R->cax.har_p) * 4; + + qua_u[7] = c3_calloc(sizeof(*qua_u[7])); + qua_u[7]->nam_c = strdup("persistent memoization cache"); + qua_u[7]->siz_w = u3h_mark(u3R->cax.per_p) * 4; + + qua_u[8] = NULL; + + c3_w sum_w = 0; + for (c3_w i_w = 0; i_w < 8; i_w++) { + sum_w += qua_u[i_w]->siz_w; + } + + u3m_quac* tot_u = c3_malloc(sizeof(*tot_u)); + tot_u->nam_c = strdup("total road stuff"); + tot_u->siz_w = sum_w; + tot_u->qua_u = qua_u; + + return tot_u; } /* u3a_reclaim(): clear ad-hoc persistent caches to reclaim memory. diff --git a/pkg/noun/allocate.h b/pkg/noun/allocate.h index b851b64c98..d0954f9656 100644 --- a/pkg/noun/allocate.h +++ b/pkg/noun/allocate.h @@ -606,8 +606,8 @@ /* u3a_mark_road(): mark ad-hoc persistent road structures. */ - c3_w - u3a_mark_road(FILE* fil_u); + u3m_quac* + u3a_mark_road(); /* u3a_reclaim(): clear ad-hoc persistent caches to reclaim memory. */ @@ -702,21 +702,35 @@ void u3a_print_time(c3_c* str_c, c3_c* cap_c, c3_d mic_d); + /* u3a_print_quac: print a quac memory report. + */ + void + u3a_print_quac(FILE* fil_u, c3_w den_w, u3m_quac* mas_u); + /* u3a_print_memory(): print memory amount. */ void u3a_print_memory(FILE* fil_u, c3_c* cap_c, c3_w wor_w); - /* u3a_prof(): mark/measure/print memory profile. RETAIN. */ - c3_w - u3a_prof(FILE* fil_u, c3_w den_w, u3_noun mas); + u3m_quac* + u3a_prof(FILE* fil_u, u3_noun mas); /* u3a_maid(): maybe print memory. */ c3_w u3a_maid(FILE* fil_u, c3_c* cap_c, c3_w wor_w); + /* u3a_quac_free(): free quac memory. + */ + void + u3a_quac_free(u3m_quac* qua_u); + + /* u3a_uncap_print_memory(): un-captioned print memory amount. + */ + void + u3a_uncap_print_memory(FILE* fil_u, c3_w byt_w); + /* u3a_deadbeef(): write 0xdeadbeef from hat to cap. */ void diff --git a/pkg/noun/jets.c b/pkg/noun/jets.c index 45e7e8144a..c0b17142ef 100644 --- a/pkg/noun/jets.c +++ b/pkg/noun/jets.c @@ -2305,27 +2305,61 @@ _cj_mark_hank(u3_noun kev, void* dat) /* u3j_mark(): mark jet state for gc. */ -c3_w -u3j_mark(FILE* fil_u) +u3m_quac* +u3j_mark() { - c3_w tot_w = 0; + u3m_quac** qua_u = c3_malloc(sizeof(*qua_u) * 7); - tot_w += u3a_maid(fil_u, " warm jet state", u3h_mark(u3R->jed.war_p)); - tot_w += u3a_maid(fil_u, " cold jet state", u3h_mark(u3R->jed.cod_p)); - tot_w += u3a_maid(fil_u, " hank cache", u3h_mark(u3R->jed.han_p)); - tot_w += u3a_maid(fil_u, " battery hash cache", u3h_mark(u3R->jed.bas_p)); + qua_u[0] = c3_calloc(sizeof(*qua_u[0])); + qua_u[0]->nam_c = strdup("warm jet state"); + qua_u[0]->siz_w = u3h_mark(u3R->jed.war_p) * 4; - { - c3_w han_w = 0; - u3h_walk_with(u3R->jed.han_p, _cj_mark_hank, &han_w); - tot_w += u3a_maid(fil_u, " call site cache", han_w); + qua_u[1] = c3_calloc(sizeof(*qua_u[1])); + qua_u[1]->nam_c = strdup("cold jet state"); + qua_u[1]->siz_w = u3h_mark(u3R->jed.cod_p) * 4; + + qua_u[2] = c3_calloc(sizeof(*qua_u[2])); + qua_u[2]->nam_c = strdup("hank cache"); + qua_u[2]->siz_w = u3h_mark(u3R->jed.han_p) * 4; + + qua_u[3] = c3_calloc(sizeof(*qua_u[3])); + qua_u[3]->nam_c = strdup("battery hash cache"); + qua_u[3]->siz_w = u3h_mark(u3R->jed.bas_p) * 4; + + qua_u[4] = c3_calloc(sizeof(*qua_u[4])); + qua_u[4]->nam_c = strdup("call site cache"); + u3h_walk_with(u3R->jed.han_p, _cj_mark_hank, &qua_u[4]->siz_w); + qua_u[4]->siz_w *= 4; + + c3_w sum_w = 0; + for ( c3_w i_w = 0; i_w < 5; i_w++ ) { + sum_w += qua_u[i_w]->siz_w; } + u3m_quac* tot_u = c3_calloc(sizeof(*tot_u)); + tot_u->nam_c = strdup("total jet stuff"); + if ( u3R == &(u3H->rod_u) ) { - tot_w += u3a_maid(fil_u, " hot jet state", u3h_mark(u3R->jed.hot_p)); - } + qua_u[5] = c3_calloc(sizeof(*qua_u[5])); + qua_u[5]->nam_c = strdup("hot jet state"); + qua_u[5]->siz_w = u3h_mark(u3R->jed.hot_p) * 4; + + sum_w += qua_u[5]->siz_w; + + qua_u[6] = NULL; + + tot_u->siz_w = sum_w; + tot_u->qua_u = qua_u; - return u3a_maid(fil_u, "total jet stuff", tot_w); + return tot_u; + } else { + qua_u[5] = NULL; + + tot_u->siz_w = sum_w; + tot_u->qua_u = qua_u; + + return tot_u; + } } /* u3j_free_hank(): free an entry from the hank cache. diff --git a/pkg/noun/jets.h b/pkg/noun/jets.h index 1440f7558a..81301d1199 100644 --- a/pkg/noun/jets.h +++ b/pkg/noun/jets.h @@ -296,8 +296,8 @@ /* u3j_mark(): mark jet state for gc. */ - c3_w - u3j_mark(FILE* fil_u); + u3m_quac* + u3j_mark(); /* u3j_free(): free jet state. */ diff --git a/pkg/noun/manage.c b/pkg/noun/manage.c index 71d673e357..1ff748d528 100644 --- a/pkg/noun/manage.c +++ b/pkg/noun/manage.c @@ -459,15 +459,17 @@ u3m_file(c3_c* pas_c) /* u3m_mark(): mark all nouns in the road. */ -c3_w -u3m_mark(FILE* fil_u) +u3m_quac** +u3m_mark(void) { - c3_w tot_w = 0; - tot_w += u3v_mark(fil_u); - tot_w += u3j_mark(fil_u); - tot_w += u3n_mark(fil_u); - tot_w += u3a_mark_road(fil_u); - return tot_w; + u3m_quac** qua_u = c3_malloc(sizeof(*qua_u) * 5); + qua_u[0] = u3v_mark(); + qua_u[1] = u3j_mark(); + qua_u[2] = u3n_mark(); + qua_u[3] = u3a_mark_road(); + qua_u[4] = NULL; + + return qua_u; } /* _pave_parts(): build internal tables. @@ -1366,7 +1368,7 @@ u3m_grab(u3_noun som, ...) // terminate with u3_none // u3h_free(u3R->cax.har_p); // u3R->cax.har_p = u3h_new(); - u3m_mark(0); + u3m_mark(); { va_list vap; u3_noun tur; diff --git a/pkg/noun/manage.h b/pkg/noun/manage.h index 14f9cc503d..974c5948f6 100644 --- a/pkg/noun/manage.h +++ b/pkg/noun/manage.h @@ -148,10 +148,19 @@ u3_noun u3m_soft_esc(u3_noun ref, u3_noun sam); + + /* u3m_quac: memory report. + */ + typedef struct _u3m_quac { + c3_c* nam_c; + c3_w siz_w; + struct _u3m_quac** qua_u; + } u3m_quac; + /* u3m_mark(): mark all nouns in the road. */ - c3_w - u3m_mark(FILE* fil_u); + u3m_quac** + u3m_mark(); /* u3m_grab(): garbage-collect the world, plus extra roots. */ diff --git a/pkg/noun/nock.c b/pkg/noun/nock.c index eb459d17f7..f2a6f62bb1 100644 --- a/pkg/noun/nock.c +++ b/pkg/noun/nock.c @@ -3047,16 +3047,30 @@ _n_bam(u3_noun kev, void* dat) /* u3n_mark(): mark the bytecode cache for gc. */ -c3_w -u3n_mark(FILE* fil_u) +u3m_quac* +u3n_mark() { - c3_w bam_w = 0, har_w = 0; + u3m_quac** qua_u = c3_malloc(sizeof(*qua_u) * 3); + + qua_u[0] = c3_calloc(sizeof(*qua_u[0])); + qua_u[0]->nam_c = strdup("bytecode programs"); + u3p(u3h_root) har_p = u3R->byc.har_p; - u3h_walk_with(har_p, _n_bam, &bam_w); + u3h_walk_with(har_p, _n_bam, &qua_u[0]->siz_w); + qua_u[0]->siz_w = qua_u[0]->siz_w * 4; + + qua_u[1] = c3_calloc(sizeof(*qua_u[1])); + qua_u[1]->nam_c = strdup("bytecode cache"); + qua_u[1]->siz_w = u3h_mark(har_p) * 4; + + qua_u[2] = NULL; + + u3m_quac* tot_u = c3_malloc(sizeof(*tot_u)); + tot_u->nam_c = strdup("total nock stuff"); + tot_u->siz_w = qua_u[0]->siz_w + qua_u[1]->siz_w; + tot_u->qua_u = qua_u; - bam_w = u3a_maid(fil_u, " bytecode programs", bam_w); - har_w = u3a_maid(fil_u, " bytecode cache", u3h_mark(har_p)); - return u3a_maid(fil_u, "total nock stuff", bam_w + har_w); + return tot_u; } /* u3n_reclaim(): clear ad-hoc persistent caches to reclaim memory. diff --git a/pkg/noun/nock.h b/pkg/noun/nock.h index 7baf7351d8..266438119d 100644 --- a/pkg/noun/nock.h +++ b/pkg/noun/nock.h @@ -123,8 +123,8 @@ /* u3n_mark(): mark bytecode cache. */ - c3_w - u3n_mark(FILE* fil_u); + u3m_quac* + u3n_mark(); /* u3n_reclaim(): clear ad-hoc persistent caches to reclaim memory. */ diff --git a/pkg/noun/vortex.c b/pkg/noun/vortex.c index 0bb9af8c29..287be49e8c 100644 --- a/pkg/noun/vortex.c +++ b/pkg/noun/vortex.c @@ -392,16 +392,33 @@ u3v_sway(u3_noun blu, c3_l tab_l, u3_noun tax) /* u3v_mark(): mark arvo kernel. */ -c3_w -u3v_mark(FILE* fil_u) +u3m_quac* +u3v_mark() { u3v_arvo* arv_u = &(u3H->arv_u); - c3_w tot_w = 0; - tot_w += u3a_maid(fil_u, " kernel", u3a_mark_noun(arv_u->roc)); - tot_w += u3a_maid(fil_u, " date", u3a_mark_noun(arv_u->now)); - tot_w += u3a_maid(fil_u, " wish cache", u3a_mark_noun(arv_u->yot)); - return u3a_maid(fil_u, "total arvo stuff", tot_w); + u3m_quac** qua_u = c3_malloc(sizeof(*qua_u) * 4); + + qua_u[0] = c3_calloc(sizeof(*qua_u[0])); + qua_u[0]->nam_c = strdup("kernel"); + qua_u[0]->siz_w = u3a_mark_noun(arv_u->roc) * 4; + + qua_u[1] = c3_calloc(sizeof(*qua_u[1])); + qua_u[1]->nam_c = strdup("date"); + qua_u[1]->siz_w = u3a_mark_noun(arv_u->now) * 4; + + qua_u[2] = c3_calloc(sizeof(*qua_u[2])); + qua_u[2]->nam_c = strdup("wish cache"); + qua_u[2]->siz_w = u3a_mark_noun(arv_u->yot) * 4; + + qua_u[3] = NULL; + + u3m_quac* tot_u = c3_malloc(sizeof(*tot_u)); + tot_u->nam_c = strdup("total arvo stuff"); + tot_u->siz_w = qua_u[0]->siz_w + qua_u[1]->siz_w + qua_u[2]->siz_w; + tot_u->qua_u = qua_u; + + return tot_u; } /* u3v_reclaim(): clear ad-hoc persistent caches to reclaim memory. @@ -434,4 +451,3 @@ u3v_rewrite_compact() arv_u->now = u3a_rewritten_noun(arv_u->now); arv_u->yot = u3a_rewritten_noun(arv_u->yot); } - diff --git a/pkg/noun/vortex.h b/pkg/noun/vortex.h index 2d202e831c..e2377fb9be 100644 --- a/pkg/noun/vortex.h +++ b/pkg/noun/vortex.h @@ -130,8 +130,8 @@ /* u3v_mark(): mark arvo kernel. */ - c3_w - u3v_mark(FILE* fil_u); + u3m_quac* + u3v_mark(); /* u3v_reclaim(): clear ad-hoc persistent caches to reclaim memory. */ diff --git a/pkg/vere/io/term.c b/pkg/vere/io/term.c index ff3f11efd2..60fa6a68fa 100644 --- a/pkg/vere/io/term.c +++ b/pkg/vere/io/term.c @@ -1603,6 +1603,13 @@ _term_io_talk(u3_auto* car_u) u3_noun wir = u3nt(c3__term, '1', u3_nul); u3_noun cad; + // send born event + // + { + cad = u3nc(c3__born, u3_nul); + _term_ovum_plan(car_u, u3k(wir), cad); + } + // send terminal dimensions // { @@ -1639,6 +1646,17 @@ _reck_orchid(u3_noun fot, u3_noun txt, c3_l* tid_l) } } +/* _term_io_quiz(): handle quiz (query to serf). +*/ +static void +_term_io_quiz(void* vod_p, u3_noun res) +{ + u3_auto* car_u = (u3_auto*)vod_p; + u3_noun wir = u3nt(c3__term, '1', u3_nul); + u3_noun cad = u3k(res); + u3_auto_plan(car_u, u3_ovum_init(0, c3__d, wir, cad)); +} + /* _term_io_kick(): apply effects. */ static c3_o @@ -1727,6 +1745,17 @@ _term_io_kick(u3_auto* car_u, u3_noun wir, u3_noun cad) ret_o = c3y; u3_pier_pack(car_u->pir_u); } break; + + case c3__quac: { + ret_o = c3y; + u3_writ* wit_u = u3_lord_writ_new(u3K.pir_u->god_u); + wit_u->typ_e = u3_writ_quiz; + wit_u->qui_u.ptr_v = car_u; + wit_u->qui_u.quiz_f = _term_io_quiz; + + u3_lord_writ_plan(u3K.pir_u->god_u, wit_u); + + } break; } } } diff --git a/pkg/vere/king.c b/pkg/vere/king.c index 9526076152..917c862036 100644 --- a/pkg/vere/king.c +++ b/pkg/vere/king.c @@ -1657,7 +1657,6 @@ u3_king_bail(void) void u3_king_grab(void* vod_p) { - c3_w tot_w = 0; FILE* fil_u; u3_assert( u3R == &(u3H->rod_u) ); @@ -1693,11 +1692,32 @@ u3_king_grab(void* vod_p) } #endif - tot_w += u3m_mark(fil_u); - tot_w += u3_pier_mark(fil_u); + u3m_quac** all_u = c3_malloc(sizeof(*all_u)*6); - u3a_print_memory(fil_u, "total marked", tot_w); - u3a_print_memory(fil_u, "sweep", u3a_sweep()); + u3m_quac** var_u = u3m_mark(); + all_u[0] = var_u[0]; + all_u[1] = var_u[1]; + all_u[2] = var_u[2]; + all_u[3] = var_u[3]; + c3_free(var_u); + + c3_w tot_w = all_u[0]->siz_w + all_u[1]->siz_w + + all_u[2]->siz_w + all_u[3]->siz_w; + + all_u[4] = c3_calloc(sizeof(*all_u[4])); + all_u[4]->nam_c = "total marked"; + all_u[4]->siz_w = tot_w; + + all_u[5] = c3_calloc(sizeof(*all_u[5])); + all_u[5]->nam_c = "sweep"; + all_u[5]->siz_w = u3a_sweep(); + + for ( c3_w i_w = 0; i_w < 6; i_w++ ) { + u3a_print_quac(fil_u, 0, all_u[i_w]); + u3a_quac_free(all_u[i_w]); + } + + c3_free(all_u); #ifdef U3_MEMORY_LOG { diff --git a/pkg/vere/lord.c b/pkg/vere/lord.c index a63824ae9b..3553aa402f 100644 --- a/pkg/vere/lord.c +++ b/pkg/vere/lord.c @@ -23,6 +23,7 @@ [%peek mil=@ sam=*] :: gang (each path $%([%once @tas @tas path] [%beam @tas beam])) [%play eve=@ lit=(list ?((pair @da ovum) *))] [%work mil=@ job=(pair @da ovum)] + [%quiz $%([%quac ~])] == :: +plea: from serf to king :: @@ -31,6 +32,7 @@ [%ripe [pro=%1 hon=@ nok=@] eve=@ mug=@] [%slog pri=@ tank] [%flog cord] + [%quiz $%([%quac p=*])] $: %peek $% [%done dat=(unit (cask))] [%bail dud=goof] @@ -521,6 +523,16 @@ _lord_plea_play(u3_lord* god_u, u3_noun dat) u3z(dat); } +/* _lord_plea_quiz(): handle quiz (query to serf). + */ +static void +_lord_plea_quiz(u3_lord* god_u, u3_noun dat) +{ + u3_writ* wit_u = _lord_writ_need(god_u, u3_writ_quiz); + wit_u->qui_u.quiz_f(wit_u->qui_u.ptr_v, dat); + u3z(dat); +} + /* _lord_work_spin(): update spinner if more work is in progress. */ static void @@ -742,15 +754,19 @@ _lord_on_plea(void* ptr_v, c3_d len_d, c3_y* byt_y) case c3__ripe: { _lord_plea_ripe(god_u, u3k(dat)); } break; + + case c3__quiz: { + _lord_plea_quiz(god_u, u3k(dat)); + } break; } u3z(jar); } -/* _lord_writ_new(): allocate a new writ. +/* u3_lord_writ_new(): allocate a new writ. */ -static u3_writ* -_lord_writ_new(u3_lord* god_u) +u3_writ* +u3_lord_writ_new(u3_lord* god_u) { u3_writ* wit_u = c3_calloc(sizeof(*wit_u)); return wit_u; @@ -812,6 +828,10 @@ _lord_writ_make(u3_lord* god_u, u3_writ* wit_u) // msg = u3nt(c3__live, c3__exit, 0); } break; + + case u3_writ_quiz: { + msg = u3nt(c3__quiz, c3__quac, u3_nul); + } break; } return msg; @@ -849,10 +869,10 @@ _lord_writ_send(u3_lord* god_u, u3_writ* wit_u) } } -/* _lord_writ_plan(): enqueue a writ and send. +/* u3_lord_writ_plan(): enqueue a writ and send. */ -static void -_lord_writ_plan(u3_lord* god_u, u3_writ* wit_u) +void +u3_lord_writ_plan(u3_lord* god_u, u3_writ* wit_u) { if ( !god_u->ent_u ) { u3_assert( !god_u->ext_u ); @@ -874,7 +894,7 @@ _lord_writ_plan(u3_lord* god_u, u3_writ* wit_u) void u3_lord_peek(u3_lord* god_u, u3_pico* pic_u) { - u3_writ* wit_u = _lord_writ_new(god_u); + u3_writ* wit_u = u3_lord_writ_new(god_u); wit_u->typ_e = u3_writ_peek; wit_u->pek_u = c3_calloc(sizeof(*wit_u->pek_u)); wit_u->pek_u->ptr_v = pic_u->ptr_v; @@ -905,7 +925,7 @@ u3_lord_peek(u3_lord* god_u, u3_pico* pic_u) // XX cache check, unless last // - _lord_writ_plan(god_u, wit_u); + u3_lord_writ_plan(god_u, wit_u); } /* u3_lord_play(): recompute batch. @@ -913,7 +933,7 @@ u3_lord_peek(u3_lord* god_u, u3_pico* pic_u) void u3_lord_play(u3_lord* god_u, u3_info fon_u) { - u3_writ* wit_u = _lord_writ_new(god_u); + u3_writ* wit_u = u3_lord_writ_new(god_u); wit_u->typ_e = u3_writ_play; wit_u->fon_u = fon_u; @@ -921,7 +941,7 @@ u3_lord_play(u3_lord* god_u, u3_info fon_u) // // u3_assert( !pay_u.ent_u->nex_u ); - _lord_writ_plan(god_u, wit_u); + u3_lord_writ_plan(god_u, wit_u); } /* u3_lord_work(): attempt work. @@ -929,7 +949,7 @@ u3_lord_play(u3_lord* god_u, u3_info fon_u) void u3_lord_work(u3_lord* god_u, u3_ovum* egg_u, u3_noun job) { - u3_writ* wit_u = _lord_writ_new(god_u); + u3_writ* wit_u = u3_lord_writ_new(god_u); wit_u->typ_e = u3_writ_work; wit_u->wok_u.egg_u = egg_u; wit_u->wok_u.job = job; @@ -943,7 +963,7 @@ u3_lord_work(u3_lord* god_u, u3_ovum* egg_u, u3_noun job) god_u->pin_o = c3y; } - _lord_writ_plan(god_u, wit_u); + u3_lord_writ_plan(god_u, wit_u); } /* u3_lord_save(): save a snapshot. @@ -955,9 +975,9 @@ u3_lord_save(u3_lord* god_u) return c3n; } else { - u3_writ* wit_u = _lord_writ_new(god_u); + u3_writ* wit_u = u3_lord_writ_new(god_u); wit_u->typ_e = u3_writ_save; - _lord_writ_plan(god_u, wit_u); + u3_lord_writ_plan(god_u, wit_u); return c3y; } } @@ -971,9 +991,9 @@ u3_lord_cram(u3_lord* god_u) return c3n; } else { - u3_writ* wit_u = _lord_writ_new(god_u); + u3_writ* wit_u = u3_lord_writ_new(god_u); wit_u->typ_e = u3_writ_cram; - _lord_writ_plan(god_u, wit_u); + u3_lord_writ_plan(god_u, wit_u); return c3y; } } @@ -983,9 +1003,9 @@ u3_lord_cram(u3_lord* god_u) void u3_lord_meld(u3_lord* god_u) { - u3_writ* wit_u = _lord_writ_new(god_u); + u3_writ* wit_u = u3_lord_writ_new(god_u); wit_u->typ_e = u3_writ_meld; - _lord_writ_plan(god_u, wit_u); + u3_lord_writ_plan(god_u, wit_u); } /* u3_lord_pack(): defragment persistent state. @@ -993,9 +1013,9 @@ u3_lord_meld(u3_lord* god_u) void u3_lord_pack(u3_lord* god_u) { - u3_writ* wit_u = _lord_writ_new(god_u); + u3_writ* wit_u = u3_lord_writ_new(god_u); wit_u->typ_e = u3_writ_pack; - _lord_writ_plan(god_u, wit_u); + u3_lord_writ_plan(god_u, wit_u); } /* u3_lord_exit(): shutdown gracefully. @@ -1003,9 +1023,9 @@ u3_lord_pack(u3_lord* god_u) void u3_lord_exit(u3_lord* god_u) { - u3_writ* wit_u = _lord_writ_new(god_u); + u3_writ* wit_u = u3_lord_writ_new(god_u); wit_u->typ_e = u3_writ_exit; - _lord_writ_plan(god_u, wit_u); + u3_lord_writ_plan(god_u, wit_u); // XX set timer, then halt } diff --git a/pkg/vere/main.c b/pkg/vere/main.c index 12c64d8ecd..3e1fdb8142 100644 --- a/pkg/vere/main.c +++ b/pkg/vere/main.c @@ -1770,7 +1770,7 @@ _cw_grab(c3_i argc, c3_c* argv[]) u3m_boot(u3_Host.dir_c, (size_t)1 << u3_Host.ops_u.lom_y); u3C.wag_w |= u3o_hashless; - u3_serf_grab(); + u3z(u3_serf_grab(c3y)); u3m_stop(); } diff --git a/pkg/vere/serf.c b/pkg/vere/serf.c index cec8bece55..c410212db9 100644 --- a/pkg/vere/serf.c +++ b/pkg/vere/serf.c @@ -26,12 +26,14 @@ :: next steps: [%peek mil=@ sam=*] :: gang (each path $%([%once @tas @tas path] [beam @tas beam])) [%play eve=@ lit=(list ?((pair @da ovum) *))] [%work mil=@ job=(pair @da ovum)] + [%quiz $%([%quac ~])] == :: +plea: from serf to king :: +$ plea $% [%live ~] [%ripe [pro=%1 hon=@ nok=@] eve=@ mug=@] + [%quiz $%([%quac p=*])] [%slog pri=@ tank] [%flog cord] $: %peek @@ -70,18 +72,70 @@ enum { _serf_fag_vega = 1 << 4 // kernel reset }; +/* _serf_quac: convert a quac to a noun. +*/ +u3_noun +_serf_quac(u3m_quac* mas_u) +{ + u3_noun list = u3_nul; + c3_w i_w = 0; + if ( mas_u->qua_u != NULL ) { + while ( mas_u->qua_u[i_w] != NULL ) { + list = u3nc(_serf_quac(mas_u->qua_u[i_w]), list); + i_w++; + } + } + list = u3kb_flop(list); + + u3_noun mas = u3nt(u3i_string(mas_u->nam_c), u3i_word(mas_u->siz_w), list); + + c3_free(mas_u->nam_c); + c3_free(mas_u->qua_u); + c3_free(mas_u); + + return mas; +} + +/* _serf_quacs: convert an array of quacs to a noun list. +*/ +u3_noun +_serf_quacs(u3m_quac** all_u) +{ + u3_noun list = u3_nul; + c3_w i_w = 0; + while ( all_u[i_w] != NULL ) { + list = u3nc(_serf_quac(all_u[i_w]), list); + i_w++; + } + c3_free(all_u); + return u3kb_flop(list); +} + +/* _serf_print_quacs: print an array of quacs. +*/ +void +_serf_print_quacs(FILE* fil_u, u3m_quac** all_u) +{ + fprintf(fil_u, "\r\n"); + c3_w i_w = 0; + while ( all_u[i_w] != NULL ) { + u3a_print_quac(fil_u, 0, all_u[i_w]); + i_w++; + } +} + /* _serf_grab(): garbage collect, checking for profiling. RETAIN. */ -static void -_serf_grab(u3_noun sac) +static u3_noun +_serf_grab(u3_noun sac, c3_o pri_o) { if ( u3_nul == sac) { if ( u3C.wag_w & (u3o_debug_ram | u3o_check_corrupt) ) { u3m_grab(sac, u3_none); } + return u3_nul; } else { - c3_w tot_w = 0; FILE* fil_u; #ifdef U3_MEMORY_LOG @@ -113,36 +167,77 @@ _serf_grab(u3_noun sac) #endif u3_assert( u3R == &(u3H->rod_u) ); - fprintf(fil_u, "\r\n"); - tot_w += u3a_maid(fil_u, "total userspace", u3a_prof(fil_u, 0, sac)); - tot_w += u3m_mark(fil_u); - tot_w += u3a_maid(fil_u, "space profile", u3a_mark_noun(sac)); + u3m_quac* pro_u = u3a_prof(fil_u, sac); + + if ( NULL == pro_u ) { + fflush(fil_u); + u3z(sac); + return u3_nul; + } else { + u3m_quac** all_u = c3_malloc(sizeof(*all_u) * 11); + all_u[0] = pro_u; + + u3m_quac** var_u = u3m_mark(); + all_u[1] = var_u[0]; + all_u[2] = var_u[1]; + all_u[3] = var_u[2]; + all_u[4] = var_u[3]; + c3_free(var_u); + + c3_w tot_w = all_u[0]->siz_w + all_u[1]->siz_w + all_u[2]->siz_w + + all_u[3]->siz_w + all_u[4]->siz_w; - u3a_print_memory(fil_u, "total marked", tot_w); - u3a_print_memory(fil_u, "free lists", u3a_idle(u3R)); - u3a_print_memory(fil_u, "sweep", u3a_sweep()); + all_u[5] = c3_calloc(sizeof(*all_u[5])); + all_u[5]->nam_c = strdup("space profile"); + all_u[5]->siz_w = u3a_mark_noun(sac) * 4; - fflush(fil_u); + tot_w += all_u[5]->siz_w; + + all_u[6] = c3_calloc(sizeof(*all_u[6])); + all_u[6]->nam_c = strdup("total marked"); + all_u[6]->siz_w = tot_w; + + all_u[7] = c3_calloc(sizeof(*all_u[7])); + all_u[7]->nam_c = strdup("free lists"); + all_u[7]->siz_w = u3a_idle(u3R) * 4; + + all_u[8] = c3_calloc(sizeof(*all_u[8])); + all_u[8]->nam_c = strdup("sweep"); + all_u[8]->siz_w = u3a_sweep() * 4; + + all_u[9] = c3_calloc(sizeof(*all_u[9])); + all_u[9]->nam_c = strdup("loom"); + all_u[9]->siz_w = u3C.wor_i * 4; + + all_u[10] = NULL; + + if ( c3y == pri_o ) { + _serf_print_quacs(fil_u, all_u); + } + fflush(fil_u); #ifdef U3_MEMORY_LOG - { - fclose(fil_u); - } + { + fclose(fil_u); + } #endif - u3z(sac); + u3_noun mas = _serf_quacs( all_u); + u3z(sac); - u3l_log(""); + return mas; + } } } /* u3_serf_grab(): garbage collect. */ -void -u3_serf_grab(void) +u3_noun +u3_serf_grab(c3_o pri_o) { u3_noun sac = u3_nul; + u3_noun res = u3_nul; u3_assert( u3R == &(u3H->rod_u) ); @@ -173,19 +268,31 @@ u3_serf_grab(void) u3z(gon); } - fprintf(stderr, "serf: measuring memory:\r\n"); - if ( u3_nul != sac ) { - _serf_grab(sac); + res = _serf_grab(sac, pri_o); } else { - u3a_print_memory(stderr, "total marked", u3m_mark(stderr)); + fprintf(stderr, "sac is empty\r\n"); + u3m_quac** var_u = u3m_mark(); + + c3_w tot_w = 0; + c3_w i_w = 0; + while ( var_u[i_w] != NULL ) { + tot_w += var_u[i_w]->siz_w; + u3a_quac_free(var_u[i_w]); + i_w++; + } + c3_free(var_u); + + u3a_print_memory(stderr, "total marked", tot_w / 4); u3a_print_memory(stderr, "free lists", u3a_idle(u3R)); u3a_print_memory(stderr, "sweep", u3a_sweep()); fprintf(stderr, "\r\n"); } fflush(stderr); + + return res; } /* u3_serf_post(): update serf state post-writ. @@ -213,7 +320,7 @@ u3_serf_post(u3_serf* sef_u) // XX this runs on replay too, |mass s/b elsewhere // if ( sef_u->fag_w & _serf_fag_mute ) { - _serf_grab(sef_u->sac); + u3z(_serf_grab(sef_u->sac, c3y)); sef_u->sac = u3_nul; } @@ -906,7 +1013,7 @@ u3_serf_live(u3_serf* sef_u, u3_noun com, u3_noun* ret) } u3m_save(); - u3_serf_grab(); + u3_serf_grab(c3y); *ret = u3nc(c3__live, u3_nul); return c3y; @@ -1024,10 +1131,22 @@ u3_serf_writ(u3_serf* sef_u, u3_noun wit, u3_noun* pel) ret_o = c3y; } } break; + case c3__quiz: { + u3z(wit); + u3_noun res = u3_serf_grab(c3n); + if ( u3_none == res ) { + ret_o = c3n; + } else { + *pel = u3nt(c3__quiz, c3__quac, res); + ret_o = c3y; + } + } break; } } - u3z(wit); + if ( tag != c3__quiz ) { + u3z(wit); + } return ret_o; } diff --git a/pkg/vere/serf.h b/pkg/vere/serf.h index 7cd2ca47d0..0645434015 100644 --- a/pkg/vere/serf.h +++ b/pkg/vere/serf.h @@ -56,7 +56,8 @@ /* u3_serf_grab(): garbage collect. */ - void - u3_serf_grab(void); + u3_noun + u3_serf_grab(c3_o pri_o); + #endif /* ifndef U3_VERE_SERF_H */ diff --git a/pkg/vere/vere.h b/pkg/vere/vere.h index 41393393ce..e669703d96 100644 --- a/pkg/vere/vere.h +++ b/pkg/vere/vere.h @@ -457,7 +457,8 @@ u3_writ_cram = 4, u3_writ_meld = 5, u3_writ_pack = 6, - u3_writ_exit = 7 + u3_writ_exit = 7, + u3_writ_quiz = 8 } u3_writ_type; /* u3_writ: ipc message from king to serf @@ -473,6 +474,10 @@ u3_peek* pek_u; // peek u3_info fon_u; // recompute c3_d eve_d; // save/pack at + struct { // serf query: + void* ptr_v; // driver + void (*quiz_f)(void*, u3_noun); // callback + } qui_u; // }; } u3_writ; @@ -768,7 +773,16 @@ u3_atom u3_time_t_in_ts(time_t tim); #endif + /* u3_lord_writ_new(): allocate a new writ. + */ + u3_writ* + u3_lord_writ_new(u3_lord* god_u); + /* u3_lord_writ_plan(): enqueue a writ and send. + */ + void + u3_lord_writ_plan(u3_lord* god_u, u3_writ* wit_u); + /* u3_time_out_ts(): struct timespec from urbit time. */ void