Various profiling and other fixes.

This commit is contained in:
C. Guy Yarvin 2014-11-30 16:06:08 -08:00
parent ee49973664
commit ce8afd76ee
12 changed files with 476 additions and 124 deletions

View File

@ -64,7 +64,7 @@ INCLUDE=i
MDEFINES=-DU3_OS_$(OS) -DU3_OS_ENDIAN_$(ENDIAN) -D U3_LIB=\"$(LIB)\"
# NOTFORCHECKIN - restore -O3
CFLAGS= $(COSFLAGS) -O3 -msse3 -ffast-math \
CFLAGS= $(COSFLAGS) -g -msse3 -ffast-math \
-funsigned-char \
-I/usr/local/include \
-I/opt/local/include \

View File

@ -325,6 +325,11 @@
u3_noun
u3a_take(u3_noun som);
/* u3a_toke(): like u3a_take(), but without touching junior memory.
*/
u3_noun
u3a_toke(u3_noun som);
/* u3a_left(): true of junior if preserved.
*/
c3_o

View File

@ -92,11 +92,18 @@
/* u3h_get(): read from hashtable.
**
** `key` is RETAINED.
** `key` is RETAINED; result is PRODUCED.
*/
u3_weak
u3h_get(u3p(u3h_root) har_p, u3_noun key);
/* u3h_git(): read from hashtable, retaining result.
**
** `key` is RETAINED; result is RETAINED.
*/
u3_weak
u3h_git(u3p(u3h_root) har_p, u3_noun key);
/* u3h_gut(): read from hashtable, unifying key nouns.
**
** `key` is RETAINED.

View File

@ -22,7 +22,8 @@
u3o_debug_cpu = 0x2, // debug: profile
u3o_check_corrupt = 0x4, // check: gc memory
u3o_check_fatal = 0x8, // check: unrecoverable
u3o_verbose = 0x10 // be remarkably wordy
u3o_verbose = 0x10, // be remarkably wordy
u3o_dryrun = 0x20 // don't touch checkpoint
};
/** Globals.

View File

@ -522,11 +522,12 @@
c3_o abo; // -a
c3_o bat; // -b, batch create
c3_o gab; // -g
c3_o dem; // -d, dem
c3_o dem; // -d, daemon
c3_o dry; // -D, dry compute
c3_o fog; // -Xwtf, skip last event
c3_o fak; // -F, fake carrier
c3_o loh; // -L, local-only networking
c3_o pro; // , profile
c3_o pro; // -P, profile
c3_o veb; // -v, verbose (inverse of -q)
c3_o nuu; // -c, new pier
c3_o vno; // -V

245
n/a.c
View File

@ -330,6 +330,8 @@ _ca_willoc(c3_w len_w, c3_w ald_w, c3_w alp_w)
}
}
extern int SUB;
/* _ca_walloc(): u3a_walloc() internals.
*/
static void*
@ -337,6 +339,27 @@ _ca_walloc(c3_w len_w, c3_w ald_w, c3_w alp_w)
{
void* ptr_v = _ca_willoc(len_w, ald_w, alp_w);
#if 0
if ( SUB ) {
fprintf(stderr, "sub: at %p; kid %p\r\n",
ptr_v,
u3R->kid_u);
fprintf(stderr, "this: hat %p, cap %p, rut %p, mat %p\r\n",
u3a_into(u3R->hat_p),
u3a_into(u3R->cap_p),
u3a_into(u3R->rut_p),
u3a_into(u3R->mat_p));
if ( u3R->kid_u ) {
fprintf(stderr, "kids: hat %p, cap %p, rut %p, mat %p\r\n\n",
u3a_into(u3R->kid_u->hat_p),
u3a_into(u3R->kid_u->cap_p),
u3a_into(u3R->kid_u->rut_p),
u3a_into(u3R->kid_u->mat_p));
}
}
#endif
#if 0
if ( u3a_botox(ptr_v) == (u3a_box*)(void *)0x27f50a02c ) {
static int xuc_i;
@ -742,6 +765,158 @@ _me_gain_use(u3_noun dog)
}
}
/* _me_coke_north_in(): coke subjuniors on a north road.
*/
static u3_noun _me_coke_north(u3_noun);
static u3_noun
_me_coke_north_in(u3_noun som)
{
c3_assert(u3_none != som);
if ( _(u3a_is_cat(som)) ) {
return som;
}
else {
u3_noun dog = som;
if ( _(u3a_north_is_senior(u3R, dog)) ) {
return dog;
}
else if ( _(u3a_north_is_junior(u3R, dog)) ) {
return _me_coke_north(dog);
}
else {
_me_gain_use(dog);
return dog;
}
}
}
/* _me_coke_north(): coke juniors on a north road.
*/
static u3_noun
_me_coke_north(u3_noun dog)
{
c3_assert(c3y == u3a_north_is_junior(u3R, dog));
if ( !_(u3a_north_is_junior(u3R, dog)) ) {
if ( !_(u3a_north_is_senior(u3R, dog)) ) {
_me_gain_use(dog);
}
return dog;
}
else {
if ( c3y == u3a_is_pom(dog) ) {
u3a_cell* old_u = u3a_to_ptr(dog);
c3_w* new_w = u3a_walloc(c3_wiseof(u3a_cell));
u3_noun new = u3a_de_twin(dog, new_w);
u3a_cell* new_u = (u3a_cell*)(void *)new_w;
new_u->mug_w = old_u->mug_w;
new_u->hed = _me_coke_north_in(old_u->hed);
new_u->tel = _me_coke_north_in(old_u->tel);
/* Don't borrow mug slot to record new destination.
*/
return new;
}
else {
u3a_atom* old_u = u3a_to_ptr(dog);
c3_w* new_w = u3a_walloc(old_u->len_w + c3_wiseof(u3a_atom));
u3_noun new = u3a_de_twin(dog, new_w);
u3a_atom* new_u = (u3a_atom*)(void *)new_w;
new_u->mug_w = old_u->mug_w;
new_u->len_w = old_u->len_w;
{
c3_w i_w;
for ( i_w=0; i_w < old_u->len_w; i_w++ ) {
new_u->buf_w[i_w] = old_u->buf_w[i_w];
}
}
/* Don't borrow mug slot to record new destination.
*/
return new;
}
}
}
/* _me_coke_south_in(): coke subjuniors on a south road.
*/
static u3_noun _me_coke_south(u3_noun);
static u3_noun
_me_coke_south_in(u3_noun som)
{
c3_assert(u3_none != som);
if ( _(u3a_is_cat(som)) ) {
return som;
}
else {
u3_noun dog = som;
if ( _(u3a_south_is_senior(u3R, dog)) ) {
return dog;
}
else if ( _(u3a_south_is_junior(u3R, dog)) ) {
return _me_coke_south(dog);
}
else {
_me_gain_use(dog);
return dog;
}
}
}
/* _me_coke_south(): coke juniors on a south road.
*/
static u3_noun
_me_coke_south(u3_noun dog)
{
c3_assert(c3y == u3a_south_is_junior(u3R, dog));
if ( !_(u3a_south_is_junior(u3R, dog)) ) {
if ( !_(u3a_south_is_senior(u3R, dog)) ) {
_me_gain_use(dog);
}
return dog;
}
else {
if ( c3y == u3a_is_pom(dog) ) {
u3a_cell* old_u = u3a_to_ptr(dog);
c3_w* new_w = u3a_walloc(c3_wiseof(u3a_cell));
u3_noun new = u3a_de_twin(dog, new_w);
u3a_cell* new_u = (u3a_cell*)(void *)new_w;
new_u->mug_w = old_u->mug_w;
new_u->hed = _me_coke_south_in(old_u->hed);
new_u->tel = _me_coke_south_in(old_u->tel);
/* Don't borrow mug slot to record new destination.
*/
return new;
}
else {
u3a_atom* old_u = u3a_to_ptr(dog);
c3_w* new_w = u3a_walloc(old_u->len_w + c3_wiseof(u3a_atom));
u3_noun new = u3a_de_twin(dog, new_w);
u3a_atom* new_u = (u3a_atom*)(void *)new_w;
new_u->mug_w = old_u->mug_w;
new_u->len_w = old_u->len_w;
{
c3_w i_w;
for ( i_w=0; i_w < old_u->len_w; i_w++ ) {
new_u->buf_w[i_w] = old_u->buf_w[i_w];
}
}
/* Don't borrow mug slot to record new destination.
*/
return new;
}
}
}
/* _me_copy_north_in(): copy subjuniors on a north road.
*/
static u3_noun _me_copy_north(u3_noun);
@ -938,6 +1113,58 @@ _me_copy_south(u3_noun dog)
}
}
/* _me_toke_north(): toke on a north road.
*/
static u3_noun
_me_toke_north(u3_noun dog)
{
if ( c3y == u3a_north_is_senior(u3R, dog) ) {
/* senior pointers are not refcounted
*/
return dog;
}
else if ( c3y == u3a_north_is_junior(u3R, dog) ) {
/* junior pointers are copied
*/
u3_noun mos = _me_copy_north(dog);
// printf("north: %p to %p\r\n", u3a_to_ptr(dog), u3a_to_ptr(mos));
return mos;
}
else {
/* normal pointers are refcounted
*/
_me_gain_use(dog);
return dog;
}
}
/* _me_toke_south(): toke on a south road.
*/
static u3_noun
_me_toke_south(u3_noun dog)
{
if ( c3y == u3a_south_is_senior(u3R, dog) ) {
/* senior pointers are not refcounted
*/
return dog;
}
else if ( c3y == u3a_south_is_junior(u3R, dog) ) {
/* junior pointers are copied
*/
u3_noun mos = _me_copy_south(dog);
// printf("south: %p to %p\r\n", u3a_to_ptr(dog), u3a_to_ptr(mos));
return mos;
}
else {
/* normal pointers are refcounted
*/
_me_gain_use(dog);
return dog;
}
}
/* _me_take_north(): take on a north road.
*/
static u3_noun
@ -1007,6 +1234,24 @@ u3a_take(u3_noun som)
}
}
/* u3a_toke(): like u3a_take(), but without touching junior memory.
*/
u3_noun
u3a_toke(u3_noun som)
{
c3_assert(u3_none != som);
if ( _(u3a_is_cat(som)) ) {
return som;
}
else {
return _(u3a_is_north(u3R))
? _me_toke_north(som)
: _me_toke_south(som);
}
}
/* u3a_left(): true of junior if preserved.
*/
c3_o

11
n/e.c
View File

@ -751,6 +751,12 @@ u3e_save(void)
{
u3_ce_patch* pat_u;
// In dry-run mode, we never touch this stuff.
//
if ( u3C.wag_w & u3o_dryrun ) {
return;
}
// Write all dirty pages to disk; clear protection and dirty bits.
//
// This has to block the main thread. All further processing can happen
@ -814,6 +820,10 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
u3P.nor_u.nam_c = "north";
u3P.sou_u.nam_c = "south";
if ( u3C.wag_w & u3o_dryrun ) {
return c3y;
}
else {
/* Open and apply any patches.
*/
if ( _(nuu_o) ) {
@ -882,6 +892,7 @@ u3e_live(c3_o nuu_o, c3_c* dir_c)
(u3P.nor_u.pgs_w + u3P.sou_u.pgs_w) << u3a_page);
}
}
}
return nuu_o;
}

41
n/h.c
View File

@ -301,25 +301,25 @@ u3h_hum(u3p(u3h_root) har_p, c3_w mug_w)
}
}
/* _ch_buck_get(): read in bucket.
/* _ch_buck_git(): read in bucket.
*/
static u3_weak
_ch_buck_get(u3h_buck* hab_u, u3_noun key)
_ch_buck_git(u3h_buck* hab_u, u3_noun key)
{
c3_w i_w;
for ( i_w = 0; i_w < hab_u->len_w; i_w++ ) {
if ( _(u3r_sing(key, u3h(hab_u->kev[i_w]))) ) {
return u3a_gain(u3t(hab_u->kev[i_w]));
return u3t(hab_u->kev[i_w]);
}
}
return u3_none;
}
/* _ch_node_get(): read in node.
/* _ch_node_git(): read in node.
*/
static u3_weak
_ch_node_get(u3h_node* han_u, c3_w lef_w, c3_w rem_w, u3_noun key)
_ch_node_git(u3h_node* han_u, c3_w lef_w, c3_w rem_w, u3_noun key)
{
c3_w bit_w, map_w;
@ -339,7 +339,7 @@ _ch_node_get(u3h_node* han_u, c3_w lef_w, c3_w rem_w, u3_noun key)
u3_noun kev = u3h_slot_to_noun(sot_w);
if ( _(u3r_sing(key, u3h(kev))) ) {
return u3a_gain(u3t(kev));
return u3t(kev);
}
else {
return u3_none;
@ -349,19 +349,19 @@ _ch_node_get(u3h_node* han_u, c3_w lef_w, c3_w rem_w, u3_noun key)
void* hav_v = u3h_slot_to_node(sot_w);
if ( 0 == lef_w ) {
return _ch_buck_get(hav_v, key);
return _ch_buck_git(hav_v, key);
}
else return _ch_node_get(hav_v, lef_w, rem_w, key);
else return _ch_node_git(hav_v, lef_w, rem_w, key);
}
}
}
/* u3h_get(): read from hashtable.
/* u3h_git(): read from hashtable.
**
** `key` is RETAINED.
** `key` is RETAINED; result is RETAINED.
*/
u3_weak
u3h_get(u3p(u3h_root) har_p, u3_noun key)
u3h_git(u3p(u3h_root) har_p, u3_noun key)
{
u3h_root* har_u = u3to(u3h_root, har_p);
c3_w mug_w = u3r_mug(key);
@ -377,7 +377,7 @@ u3h_get(u3p(u3h_root) har_p, u3_noun key)
if ( _(u3r_sing(key, u3h(kev))) ) {
har_u->sot_w[inx_w] = u3h_noun_be_warm(sot_w);
return u3a_gain(u3t(kev));
return u3t(kev);
}
else {
return u3_none;
@ -386,10 +386,25 @@ u3h_get(u3p(u3h_root) har_p, u3_noun key)
else {
u3h_node* han_u = u3h_slot_to_node(sot_w);
return _ch_node_get(han_u, 25, rem_w, key);
return _ch_node_git(han_u, 25, rem_w, key);
}
}
/* u3h_get(): read from hashtable.
**
** `key` is RETAINED; result is PRODUCED.
*/
u3_weak
u3h_get(u3p(u3h_root) har_p, u3_noun key)
{
u3_noun pro = u3h_git(har_p, key);
if ( u3_none != pro ) {
u3a_gain(pro);
}
return pro;
}
/* _ch_buck_gut(): read in bucket, unifying key nouns.
*/
static u3_weak

14
n/m.c
View File

@ -278,6 +278,8 @@ _cm_signal_deep(c3_w sec_w)
setitimer(ITIMER_VIRTUAL, &itm_u, 0);
signal(SIGVTALRM, _cm_signal_handle_alrm);
}
u3t_boot();
}
/* _cm_signal_done():
@ -299,6 +301,7 @@ _cm_signal_done()
setitimer(ITIMER_VIRTUAL, &itm_u, 0);
}
u3_unix_ef_move();
u3t_boff();
}
/* u3m_signal(): treat a nock-level exception as a signal interrupt.
@ -619,16 +622,19 @@ u3m_leap(c3_w pad_w)
/* Measure the pad - we'll need it.
*/
{
#if 0
if ( pad_w < u3R->all.fre_w ) {
pad_w = 0;
}
else {
pad_w -= u3R->all.fre_w;
}
#endif
if ( (pad_w + c3_wiseof(u3a_road)) >= u3a_open(u3R) ) {
u3m_bail(c3__meme);
}
len_w = u3a_open(u3R) - (pad_w + c3_wiseof(u3a_road));
// fprintf(stderr, "leap: pad %d, len %x\r\n", pad_w, len_w);
}
/* Allocate a region on the cap.
@ -855,7 +861,7 @@ u3m_soft_top(c3_w sec_w, // timer seconds
u3_noun
u3m_soft_sure(u3_funk fun_f, u3_noun arg)
{
u3_noun pro, pru = u3m_soft_top(0, 32768, fun_f, arg);
u3_noun pro, pru = u3m_soft_top(0, (1 << 17), fun_f, arg);
c3_assert(_(u3du(pru)));
pro = u3k(u3t(pru));
@ -894,7 +900,7 @@ u3m_soft_run(u3_noun fly,
/* Record the cap, and leap.
*/
u3m_hate(32768);
u3m_hate(1 << 17);
/* Configure the new road.
*/
@ -982,7 +988,7 @@ u3m_soft_esc(u3_noun sam)
/* Record the cap, and leap.
*/
u3m_hate(32768);
u3m_hate(1 << 17);
/* Configure the new road.
*/
@ -1352,7 +1358,7 @@ _cm_signals(void)
// Block SIGPROF, so that if/when we reactivate it on the
// main thread for profiling, we won't get hits in paralle
// main thread for profiling, we won't get hits in parallel
// on other threads.
{
sigset_t set;

110
n/t.c
View File

@ -3,6 +3,7 @@
** This file is in the public domain.
*/
#include "all.h"
#include <pthread.h>
/* u3t_push(): push on trace stack.
*/
@ -79,6 +80,26 @@ u3t_heck(u3_atom cog)
}
}
/* _t_jet_label():
*/
u3_weak
_t_jet_label(u3a_road* rod_u, u3_noun bat)
{
while ( 1 ) {
u3_weak cax = u3h_git(rod_u->jed.har_p, bat);
if ( u3_none != cax ) {
return u3h(u3t(u3t(u3h(cax))));
}
if ( rod_u->par_u ) {
rod_u = rod_u->par_u;
}
else return u3_none;
}
}
#if 1
/* _t_samp_process(): process raw sample data from live road.
*/
static u3_noun
@ -95,34 +116,18 @@ _t_samp_process(u3_road* rod_u)
while ( u3_nul != don ) {
u3_noun bat = u3h(don);
u3_noun laj, lab;
u3_noun lab;
// Find the label from this battery, surface allocated.
//
{
u3R = rod_u;
{
u3_noun cax;
u3_noun laj = _t_jet_label(rod_u, bat);
if ( u3_none == laj ) { abort(); }
if ( u3_none == (cax = u3j_find(bat)) ) {
abort(); // probably a little drastic
}
laj = u3h(u3t(u3t(u3h(cax))));
#if 0
fprintf(stderr, "laj %x, mug %x, use %d, jr %d\r\n",
laj,
u3r_mug(laj),
u3a_use(laj),
u3a_is_junior((&u3H->rod_u), laj));
u3m_p("label", laj);
#endif
}
u3R = &u3H->rod_u;
// lab = u3a_take(laj); u3a_wash(laj);
lab = u3a_take(laj);
u3a_wash(laj);
lab = u3a_toke(laj);
}
// Add the label to the traced label stack, trimming recursion.
//
{
@ -152,6 +157,7 @@ _t_samp_process(u3_road* rod_u)
}
rod_u = rod_u->par_u;
}
u3z(muf);
// Lose the maps and save a pure label stack in original order.
//
@ -172,17 +178,56 @@ _t_samp_process(u3_road* rod_u)
return pal;
}
}
#endif
int SAM;
int SUB;
pthread_t ONLY;
/* u3t_samp(): sample.
*/
void
u3t_samp(void)
{
c3_w sam = SAM;
// Ghetto semaphore!
//
if ( !ONLY ) {
ONLY = pthread_self();
}
else if ( ONLY != pthread_self() ) {
c3_d one_d, two_d;
SAM++;
fprintf(stderr, "only %p, this %p\r\n", ONLY, pthread_self());
pthread_threadid_np(ONLY, &one_d);
pthread_threadid_np(pthread_self(), &two_d);
fprintf(stderr, "one %llu, two %llu\r\n", one_d, two_d);
abort();
return;
}
#if 0
if ( &(u3H->rod_u) != u3R ) {
u3a_road* rod_u = u3R;
u3R = &(u3H->rod_u);
{
c3_w i_w;
u3_noun som[64];
SUB = 1;
for ( i_w = 0; i_w < 64; i_w++ ) {
som[i_w] = u3nc(i_w, i_w);
}
for ( i_w = 0; i_w < 64; i_w++ ) {
u3z(som[i_w]);
}
SUB = 0;
}
u3R = rod_u;
}
return;
#endif
// Profile sampling, because it allocates on the home road,
// only works on when we're not at home.
@ -194,6 +239,11 @@ u3t_samp(void)
u3R = &(u3H->rod_u);
{
u3_noun lab = _t_samp_process(rod_u);
#if 0
u3z(lab);
u3R = rod_u;
return;
#endif
c3_assert(u3R == &u3H->rod_u);
if ( 0 == u3R->pro.day ) {
@ -224,8 +274,8 @@ u3t_flee(void)
{
u3_noun t_don = u3k(u3t(u3R->pro.don));
u3z(u3R->pro.don);
u3R->pro.don = t_don;
u3z(u3R->pro.don);
}
/* u3t_damp(): print and clear profile data.
@ -233,19 +283,18 @@ u3t_flee(void)
void
u3t_damp(void)
{
u3m_p("day", u3R->pro.day);
if ( 0 != u3R->pro.day ) {
u3_noun wol = u3do("pi-tell", u3R->pro.day);
u3m_wall(wol);
u3R->pro.day = u3v_do("doss", 0);
}
#if 0
if ( 0 != u3R->pro.nox_d ) {
printf("knox: %llu\r\n", (u3R->pro.nox_d / 1000ULL));
u3R->pro.nox_d = 0;
}
#endif
}
/* _ct_sigaction(): profile sigaction callback.
@ -262,11 +311,6 @@ void
u3t_boot(void)
{
if ( u3C.wag_w & u3o_debug_cpu ) {
printf("ct: now profiling.\r\n");
printf("knox: %llu\r\n", (u3R->pro.nox_d / 1000ULL));
u3R->pro.nox_d = 0;
#if defined(U3_OS_osx)
#if 1
{

View File

@ -641,14 +641,23 @@ u3_lo_loop()
// signal(SIGIO, SIG_IGN); // linux is wont to produce for some reason
_lo_init();
u3_raft_init();
u3t_boot(); // activate profiling
if ( _(u3_Host.ops_u.dry) ) {
u3t_boff();
u3t_damp();
u3_lo_exit();
fprintf(stderr, "dry run: exit\r\n");
exit(0);
}
else {
if ( c3n == u3_Host.ops_u.bat ) {
uv_run(u3L, UV_RUN_DEFAULT);
}
}
}
/* u3_lo_lead(): actions on promotion to leader.
*/

View File

@ -57,12 +57,13 @@ _main_getopt(c3_i argc, c3_c** argv)
u3_Host.ops_u.fog = c3n;
u3_Host.ops_u.fak = c3n;
u3_Host.ops_u.pro = c3n;
u3_Host.ops_u.dry = c3n;
u3_Host.ops_u.veb = c3y;
u3_Host.ops_u.nuu = c3n;
u3_Host.ops_u.mem = c3n;
u3_Host.ops_u.kno_w = DefaultKernel;
while ( (ch_i = getopt(argc, argv, "I:X:f:k:l:n:p:r:LabcdgqvFMP")) != -1 ) {
while ( (ch_i = getopt(argc, argv, "I:X:f:k:l:n:p:r:LabcdgqvFMPD")) != -1 ) {
switch ( ch_i ) {
case 'M': {
u3_Host.ops_u.mem = c3y;
@ -122,6 +123,7 @@ _main_getopt(c3_i argc, c3_c** argv)
case 'd': { u3_Host.ops_u.dem = c3y; break; }
case 'g': { u3_Host.ops_u.gab = c3y; break; }
case 'P': { u3_Host.ops_u.pro = c3y; break; }
case 'D': { u3_Host.ops_u.dry = c3y; break; }
case 'q': { u3_Host.ops_u.veb = c3n; break; }
case 'v': { u3_Host.ops_u.veb = c3y; break; }
case '?': default: {
@ -328,6 +330,12 @@ main(c3_i argc,
if ( _(u3_Host.ops_u.veb) ) {
u3C.wag_w |= u3o_verbose;
}
/* Set dry-run flag.
*/
if ( _(u3_Host.ops_u.dry) ) {
u3C.wag_w |= u3o_dryrun;
}
}
u3m_boot(u3_Host.ops_u.nuu, u3_Host.ops_u.gab, u3_Host.dir_c);