From f811d7b35ee28dfc7328a8b2d0d0c31d72da054b Mon Sep 17 00:00:00 2001 From: Sigilante Date: Thu, 9 May 2024 15:31:59 -0500 Subject: [PATCH 1/7] Start %jinx hint. --- pkg/c3/motes.h | 1 + pkg/noun/nock.c | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/pkg/c3/motes.h b/pkg/c3/motes.h index 975554e94b..5881f5f38e 100644 --- a/pkg/c3/motes.h +++ b/pkg/c3/motes.h @@ -618,6 +618,7 @@ # define c3__jato c3_s4('j','a','t','o') # define c3__jet c3_s3('j','e','t') # define c3__jetd c3_s4('j','e','t','d') +# define c3__jinx c3_s4('j','i','n','x') # define c3__just c3_s4('j','u','s','t') # define c3__k c3_s1('k') # define c3__khan c3_s4('k','h','a','n') diff --git a/pkg/noun/nock.c b/pkg/noun/nock.c index 452b04c309..fe22e6fb97 100644 --- a/pkg/noun/nock.c +++ b/pkg/noun/nock.c @@ -1022,7 +1022,8 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o) case c3__meme: case c3__nara: case c3__hela: - case c3__bout: { + case c3__bout: + case c3__jinx: { u3_noun fen = u3_nul; c3_w nef_w = _n_comp(&fen, nef, los_o, c3n); // add appropriate hind opcode @@ -1060,7 +1061,8 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o) case c3__meme: case c3__nara: case c3__hela: - case c3__bout: { + case c3__bout: + case c3__jinx: { u3_noun fen = u3_nul; c3_w nef_w = _n_comp(&fen, nef, los_o, c3n); // add appropriate hind opcode @@ -1872,6 +1874,11 @@ _n_hilt_fore(u3_noun hin, u3_noun bus, u3_noun* out) *out = u3_nul; } break; + case c3__jinx: { + u3_atom now = u3i_chub(u3t_trace_time()); + *out = u3i_cell(tag, now); + } break; + default: { *out = u3_nul; } break; @@ -1896,6 +1903,13 @@ _n_hilt_hind(u3_noun tok, u3_noun pro) u3t_slog(u3nc(0, u3i_string(str_c))); u3z(delta); } + else if ( (c3y == u3r_cell(tok, &p_tok, &q_tok)) && (c3__jinx == p_tok) ) { + u3_atom delta = u3ka_sub(u3i_chub(u3t_trace_time()), u3k(q_tok)); + c3_c str_c[64]; + u3a_print_time(str_c, "jinxed at", u3r_chub(0, delta)); + u3t_slog(u3nc(0, u3i_string(str_c))); + u3z(delta); + } else { u3_assert( u3_nul == tok ); } @@ -1924,6 +1938,11 @@ _n_hint_fore(u3_cell hin, u3_noun bus, u3_noun* clu) *clu = u3nt(u3k(tag), *clu, now); } break; + case c3__jinx: { + u3_atom now = u3i_chub(u3t_trace_time()); + *clu = u3nt(u3k(tag), *clu, now); + } break; + case c3__nara: { u3_noun pri, tan; if ( c3y == u3r_cell(*clu, &pri, &tan) ) { From b628584aaa65bb7b68d71c028129238fce5f5926 Mon Sep 17 00:00:00 2001 From: Sigilante Date: Fri, 10 May 2024 11:34:33 -0500 Subject: [PATCH 2/7] Post stub for jinx hint. --- pkg/noun/nock.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/pkg/noun/nock.c b/pkg/noun/nock.c index fe22e6fb97..0dc9a1fca5 100644 --- a/pkg/noun/nock.c +++ b/pkg/noun/nock.c @@ -16,6 +16,8 @@ #include "xtract.h" #include "zave.h" +#include + // define to have each opcode printed as it executes, // along with some other debugging info # undef VERBOSE_BYTECODE @@ -1022,8 +1024,7 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o) case c3__meme: case c3__nara: case c3__hela: - case c3__bout: - case c3__jinx: { + case c3__bout: { u3_noun fen = u3_nul; c3_w nef_w = _n_comp(&fen, nef, los_o, c3n); // add appropriate hind opcode @@ -1061,8 +1062,7 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o) case c3__meme: case c3__nara: case c3__hela: - case c3__bout: - case c3__jinx: { + case c3__bout: { u3_noun fen = u3_nul; c3_w nef_w = _n_comp(&fen, nef, los_o, c3n); // add appropriate hind opcode @@ -1106,6 +1106,15 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o) tot_w += _n_comp(ops, nef, los_o, tel_o); break; + case c3__jinx: + fprintf(stderr, "nock: jinx not implemented\r\n"); + fprintf(stderr, "zep: %x hod: %x nef: %x\r\n", zep, u3x_at(1, hod), u3x_at(1, nef)); + tot_w += _n_comp(ops, hod, c3n, c3n); + ++tot_w; _n_emit(ops, u3nc(BUSH, zep)); // overflows to SUSH + tot_w += _n_comp(ops, nef, los_o, c3n); + ++tot_w; _n_emit(ops, DROP); + break; + // germ and sole are unused... case c3__fast: @@ -1874,11 +1883,6 @@ _n_hilt_fore(u3_noun hin, u3_noun bus, u3_noun* out) *out = u3_nul; } break; - case c3__jinx: { - u3_atom now = u3i_chub(u3t_trace_time()); - *out = u3i_cell(tag, now); - } break; - default: { *out = u3_nul; } break; @@ -1903,13 +1907,6 @@ _n_hilt_hind(u3_noun tok, u3_noun pro) u3t_slog(u3nc(0, u3i_string(str_c))); u3z(delta); } - else if ( (c3y == u3r_cell(tok, &p_tok, &q_tok)) && (c3__jinx == p_tok) ) { - u3_atom delta = u3ka_sub(u3i_chub(u3t_trace_time()), u3k(q_tok)); - c3_c str_c[64]; - u3a_print_time(str_c, "jinxed at", u3r_chub(0, delta)); - u3t_slog(u3nc(0, u3i_string(str_c))); - u3z(delta); - } else { u3_assert( u3_nul == tok ); } @@ -1938,11 +1935,6 @@ _n_hint_fore(u3_cell hin, u3_noun bus, u3_noun* clu) *clu = u3nt(u3k(tag), *clu, now); } break; - case c3__jinx: { - u3_atom now = u3i_chub(u3t_trace_time()); - *clu = u3nt(u3k(tag), *clu, now); - } break; - case c3__nara: { u3_noun pri, tan; if ( c3y == u3r_cell(*clu, &pri, &tan) ) { From dda464411b2ec76422451f7926db9bc09553a3b7 Mon Sep 17 00:00:00 2001 From: Sigilante Date: Fri, 17 May 2024 14:47:40 -0500 Subject: [PATCH 3/7] Add working %jinx hint. --- pkg/noun/manage.c | 26 +++++++++++++++++++++++++- pkg/noun/manage.h | 10 ++++++++++ pkg/noun/nock.c | 36 ++++++++++++++++++++++++++---------- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/pkg/noun/manage.c b/pkg/noun/manage.c index d880a42032..a11f7033c4 100644 --- a/pkg/noun/manage.c +++ b/pkg/noun/manage.c @@ -367,6 +367,20 @@ _cm_signal_deep(c3_w mil_w) ); } + u3m_timer_set(mil_w); + + // factor into own function, call here and in _n_hint_fore() TODO + // _n_hint_hind() will look like this w/ deinstall handler instead + // return void b/c just clearing timer, no args + + u3t_boot(); +} + +/* u3m_timer_set +*/ +void +u3m_timer_set(c3_w mil_w) +{ if ( mil_w ) { struct itimerval itm_u; @@ -381,8 +395,18 @@ _cm_signal_deep(c3_w mil_w) rsignal_install_handler(SIGVTALRM, _cm_signal_handle_alrm); } } +} - u3t_boot(); +/* u3m_timer_clear +*/ +void +u3m_timer_clear() +{ + struct itimerval itm_u; + + timerclear(&itm_u.it_interval); + + rsignal_deinstall_handler(SIGVTALRM); } /* _cm_signal_done(): diff --git a/pkg/noun/manage.h b/pkg/noun/manage.h index 14f9cc503d..890c8ad134 100644 --- a/pkg/noun/manage.h +++ b/pkg/noun/manage.h @@ -198,4 +198,14 @@ c3_w u3m_pack(void); + /* u3m_timer_set: set the timer. + */ + void + u3m_timer_set(c3_w mil_w); + + /* u3m_timer_clear: clear the timer. + */ + void + u3m_timer_clear(void); + #endif /* ifndef U3_MANAGE_H */ diff --git a/pkg/noun/nock.c b/pkg/noun/nock.c index 0dc9a1fca5..6313c0211b 100644 --- a/pkg/noun/nock.c +++ b/pkg/noun/nock.c @@ -1062,6 +1062,7 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o) case c3__meme: case c3__nara: case c3__hela: + case c3__jinx: case c3__bout: { u3_noun fen = u3_nul; c3_w nef_w = _n_comp(&fen, nef, los_o, c3n); @@ -1106,15 +1107,6 @@ _n_bint(u3_noun* ops, u3_noun hif, u3_noun nef, c3_o los_o, c3_o tel_o) tot_w += _n_comp(ops, nef, los_o, tel_o); break; - case c3__jinx: - fprintf(stderr, "nock: jinx not implemented\r\n"); - fprintf(stderr, "zep: %x hod: %x nef: %x\r\n", zep, u3x_at(1, hod), u3x_at(1, nef)); - tot_w += _n_comp(ops, hod, c3n, c3n); - ++tot_w; _n_emit(ops, u3nc(BUSH, zep)); // overflows to SUSH - tot_w += _n_comp(ops, nef, los_o, c3n); - ++tot_w; _n_emit(ops, DROP); - break; - // germ and sole are unused... case c3__fast: @@ -1935,6 +1927,26 @@ _n_hint_fore(u3_cell hin, u3_noun bus, u3_noun* clu) *clu = u3nt(u3k(tag), *clu, now); } break; + case c3__jinx: { + if (c3y == u3a_is_atom(*clu)) { + // clu is in Urbit time, but we need Unix time + mpz_t clu_mp; + u3r_mp(clu_mp, *clu); + mpz_t urs_mp, tim_mp; + mpz_init(urs_mp); + mpz_init(tim_mp); + mpz_tdiv_q_2exp(tim_mp, clu_mp, 48); + mpz_mul_ui(tim_mp, tim_mp, 1000); + mpz_tdiv_q_2exp(urs_mp, tim_mp, 16); + c3_w mil_w = u3i_mp(urs_mp); + u3m_timer_set(mil_w); // set ITIMER (mil_w is in microseconds) + mpz_clear(clu_mp); + mpz_clear(tim_mp); + } + u3z(*clu); + *clu = c3__jinx; + } break; + case c3__nara: { u3_noun pri, tan; if ( c3y == u3r_cell(*clu, &pri, &tan) ) { @@ -1996,7 +2008,11 @@ static void _n_hint_hind(u3_noun tok, u3_noun pro) { u3_noun p_tok, q_tok, r_tok; - if ( (c3y == u3r_trel(tok, &p_tok, &q_tok, &r_tok)) && (c3__bout == p_tok) ) { + if (c3__jinx == tok) { + u3m_timer_clear(); + // call fn in u3m to cancel ITIMER (we know no parent timer now until we add nesting) + } + else if ( (c3y == u3r_trel(tok, &p_tok, &q_tok, &r_tok)) && (c3__bout == p_tok) ) { // get the microseconds elapsed u3_atom delta = u3ka_sub(u3i_chub(u3t_trace_time()), u3k(r_tok)); From 500815b81687c421551ac5bf3fbb98fc83ba513f Mon Sep 17 00:00:00 2001 From: Sigilante Date: Fri, 17 May 2024 15:04:45 -0500 Subject: [PATCH 4/7] Remove spurious comment --- pkg/noun/nock.c | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/noun/nock.c b/pkg/noun/nock.c index 6313c0211b..89f7d10b70 100644 --- a/pkg/noun/nock.c +++ b/pkg/noun/nock.c @@ -2010,7 +2010,6 @@ _n_hint_hind(u3_noun tok, u3_noun pro) u3_noun p_tok, q_tok, r_tok; if (c3__jinx == tok) { u3m_timer_clear(); - // call fn in u3m to cancel ITIMER (we know no parent timer now until we add nesting) } else if ( (c3y == u3r_trel(tok, &p_tok, &q_tok, &r_tok)) && (c3__bout == p_tok) ) { // get the microseconds elapsed From 047105ae687dc1049a7e30aa459a62a31e1aca10 Mon Sep 17 00:00:00 2001 From: Sigilante Date: Tue, 1 Oct 2024 14:09:13 -0500 Subject: [PATCH 5/7] WIP adding stack support for timer --- pkg/noun/manage.c | 166 ++++++++++++++++++++++++++++- pkg/noun/manage.h | 19 ++++ pkg/noun/nock.c | 20 ++-- pkg/noun/platform/darwin/rsignal.h | 1 + pkg/noun/platform/linux/rsignal.h | 1 + 5 files changed, 190 insertions(+), 17 deletions(-) diff --git a/pkg/noun/manage.c b/pkg/noun/manage.c index a11f7033c4..838b50daf2 100644 --- a/pkg/noun/manage.c +++ b/pkg/noun/manage.c @@ -30,6 +30,10 @@ // #undef NO_OVERFLOW +/** Global variables. +**/ + static timer_stack *stk_u; + /* (u3_noun)setjmp(u3R->esc.buf): setjmp within road. */ #if 0 @@ -376,14 +380,51 @@ _cm_signal_deep(c3_w mil_w) u3t_boot(); } -/* u3m_timer_set +// Function to add an `itimerval` to a `timeval` +struct timeval __add_itimer(struct timeval base_time, struct itimerval timer) { + struct timeval result; + + // Add seconds + result.tv_sec = base_time.tv_sec + timer.it_value.tv_sec; + + // Add microseconds + result.tv_usec = base_time.tv_usec + timer.it_value.tv_usec; + + // Handle microsecond overflow + if (result.tv_usec >= 1000000) { + result.tv_sec += 1; + result.tv_usec -= 1000000; + } + + return result; +} + +// Function to calculate the interval between two `timeval` structs +struct itimerval __get_interval(struct timeval start, struct timeval end) { + struct itimerval interval; + + // Calculate the difference in seconds and microseconds + interval.it_value.tv_sec = end.tv_sec - start.tv_sec; + interval.it_value.tv_usec = end.tv_usec - start.tv_usec; + + // Handle underflow of microseconds (i.e., if end's microseconds < start's microseconds) + if (interval.it_value.tv_usec < 0) { + interval.it_value.tv_sec -= 1; + interval.it_value.tv_usec += 1000000; + } + + timerclear(&interval.it_interval); + + return interval; +} + +/* u3m_timer_set: set interval timer for mil_w milliseconds */ void u3m_timer_set(c3_w mil_w) { if ( mil_w ) { struct itimerval itm_u; - timerclear(&itm_u.it_interval); itm_u.it_value.tv_sec = (mil_w / 1000); itm_u.it_value.tv_usec = 1000 * (mil_w % 1000); @@ -402,11 +443,122 @@ u3m_timer_set(c3_w mil_w) void u3m_timer_clear() { - struct itimerval itm_u; + rsignal_deinstall_handler(SIGVTALRM); +} +/* u3m_timer_push: set interval timer against walltime +*/ +void +u3m_timer_push(c3_w mil_w) +{ + fprintf(stderr, "pushing timer %d\n", mil_w); + // get the request timer interval + struct itimerval itm_u; timerclear(&itm_u.it_interval); + itm_u.it_value.tv_sec = (mil_w / 1000); + itm_u.it_value.tv_usec = 1000 * (mil_w % 1000); + fprintf(stderr, "interval: %d s %d us\n", itm_u.it_value.tv_sec, itm_u.it_value.tv_usec); + + // does the stack have anything on it? if it's clean, this is easy: + fprintf(stderr, "checking stack\n"); + fprintf(stderr, "checking stack %x\n", stk_u->top); + if (stk_u->top == NULL) { + fprintf(stderr, "no timer on stack\n"); + // if not, set the timer and return + if ( rsignal_setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) { + u3l_log("loom: push timer failed %s", strerror(errno)); + } + else { + // keep the expiry walltime in the stack + struct timeval tim_u; + gettimeofday(&tim_u, 0); - rsignal_deinstall_handler(SIGVTALRM); + // debugging, TODO remove + c3_d tim_d = 1000000ULL * tim_u.tv_sec + tim_u.tv_usec; + fprintf(stderr, "expiry: %lx us\n", tim_d); + + struct timer* new_u = (timer*)u3a_malloc(sizeof(timer)); + new_u->wal_u = tim_u; + new_u->nex_u = stk_u->top; + stk_u->top = new_u; + + rsignal_install_handler(SIGVTALRM, _cm_signal_handle_alrm); + } + return; + } + + // check that it is less than the current remaining interval + struct itimerval cur_u; + + rsignal_getitimer(ITIMER_VIRTUAL, &cur_u); + // zero if no timer is set + fprintf(stderr, "current interval: %d s %d us\n", cur_u.it_value.tv_sec, cur_u.it_value.tv_usec); + + if (timercmp(&cur_u.it_value, &itm_u.it_value, <)) { + u3l_log("loom: nest timer failed, too large for remaining time %s", + strerror(errno)); + } + + // otherwise set the timer + struct itimerval rem_u; + + timersub(&cur_u.it_value, &itm_u.it_value, &rem_u.it_value); + + if ( rsignal_setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) { + u3l_log("loom: nest timer failed %s", strerror(errno)); + } + else { + // keep the expiry walltime in the stack + struct timeval tim_u; + gettimeofday(&tim_u, 0); + + // debugging, TODO remove + c3_d tim_d = 1000000ULL * tim_u.tv_sec + tim_u.tv_usec; + fprintf(stderr, "expiry: %lx us\n", tim_d); + c3_d cur_d = cur_u.it_value.tv_sec * 1000 + cur_u.it_value.tv_usec / 1000; + fprintf(stderr, "remaining: %lx ms\n", cur_d); + + struct timer* new_u = (timer*)u3a_malloc(sizeof(timer)); + new_u->wal_u = __add_itimer(tim_u, cur_u); + new_u->nex_u = stk_u->top; + stk_u->top = new_u; + + rsignal_install_handler(SIGVTALRM, _cm_signal_handle_alrm); + } +} + +/* u3m_timer_pop +*/ +void +u3m_timer_pop() +{ + if (stk_u->top == NULL) { + u3l_log("loom: no \%jinx timer to pop"); + } + else { + timer *old_u = stk_u->top; + stk_u->top = stk_u->top->nex_u; + + if (stk_u->top == NULL) { + u3m_timer_clear(); + return; + } + + struct timeval nex_u = stk_u->top->wal_u; + struct timeval tim_u; + gettimeofday(&tim_u, 0); + struct itimerval itm_u; + itm_u = __get_interval(tim_u, nex_u); + + if ( rsignal_setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) { + u3l_log("loom: pop timer failed %s", strerror(errno)); + } + else { + rsignal_install_handler(SIGVTALRM, _cm_signal_handle_alrm); + } + + free(old_u); + } } /* _cm_signal_done(): @@ -2101,6 +2253,11 @@ u3m_init(size_t len_i) u3C.wor_i = len_i >> 2; u3l_log("loom: mapped %zuMB", len_i >> 20); } + + // start %jinx timer stack + // + fprintf(stderr, "jinx: start\r\n"); + // stk_u->top = (timer*)NULL; } extern void u3je_secp_stop(void); @@ -2207,6 +2364,7 @@ u3m_boot(c3_c* dir_c, size_t len_i) memset(u3A, 0, sizeof(*u3A)); return 0; } + } /* u3m_boot_lite(): start without checkpointing. diff --git a/pkg/noun/manage.h b/pkg/noun/manage.h index 890c8ad134..c6ae5ddeec 100644 --- a/pkg/noun/manage.h +++ b/pkg/noun/manage.h @@ -208,4 +208,23 @@ void u3m_timer_clear(void); + /* u3m_timer_push: push a timer on the stack. + */ + void + u3m_timer_push(c3_w mil_w); + + /* u3m_timer_pop: pop a timer from the stack. + */ + void + u3m_timer_pop(void); + + typedef struct timer { + struct timeval wal_u; + struct timer* nex_u; + } timer; + + typedef struct timer_stack { + timer* top; + } timer_stack; + #endif /* ifndef U3_MANAGE_H */ diff --git a/pkg/noun/nock.c b/pkg/noun/nock.c index 89f7d10b70..5ac0a712aa 100644 --- a/pkg/noun/nock.c +++ b/pkg/noun/nock.c @@ -1930,18 +1930,12 @@ _n_hint_fore(u3_cell hin, u3_noun bus, u3_noun* clu) case c3__jinx: { if (c3y == u3a_is_atom(*clu)) { // clu is in Urbit time, but we need Unix time - mpz_t clu_mp; - u3r_mp(clu_mp, *clu); - mpz_t urs_mp, tim_mp; - mpz_init(urs_mp); - mpz_init(tim_mp); - mpz_tdiv_q_2exp(tim_mp, clu_mp, 48); - mpz_mul_ui(tim_mp, tim_mp, 1000); - mpz_tdiv_q_2exp(urs_mp, tim_mp, 16); - c3_w mil_w = u3i_mp(urs_mp); - u3m_timer_set(mil_w); // set ITIMER (mil_w is in microseconds) - mpz_clear(clu_mp); - mpz_clear(tim_mp); + c3_d tim_d; + if ( c3y == u3r_safe_chub(*clu, &tim_d) ) { + c3_w mil_w = u3_time_msc_out(tim_d); + fprintf(stderr, "u3t_jinx_time 2: %lld -> %u\n", tim_d, mil_w); + // u3m_timer_push(mil_w); + } } u3z(*clu); *clu = c3__jinx; @@ -2009,7 +2003,7 @@ _n_hint_hind(u3_noun tok, u3_noun pro) { u3_noun p_tok, q_tok, r_tok; if (c3__jinx == tok) { - u3m_timer_clear(); + u3m_timer_pop(); } else if ( (c3y == u3r_trel(tok, &p_tok, &q_tok, &r_tok)) && (c3__bout == p_tok) ) { // get the microseconds elapsed diff --git a/pkg/noun/platform/darwin/rsignal.h b/pkg/noun/platform/darwin/rsignal.h index a14670e19a..bdf75286e6 100644 --- a/pkg/noun/platform/darwin/rsignal.h +++ b/pkg/noun/platform/darwin/rsignal.h @@ -9,5 +9,6 @@ #define rsignal_install_handler signal #define rsignal_deinstall_handler(sig) signal((sig), SIG_IGN) #define rsignal_setitimer setitimer +#define rsignal_getitimer getitimer #endif /* ifndef NOUN_PLATFORM_DARWIN_RSIGNAL_H */ diff --git a/pkg/noun/platform/linux/rsignal.h b/pkg/noun/platform/linux/rsignal.h index 9c55cee945..0507751f1c 100644 --- a/pkg/noun/platform/linux/rsignal.h +++ b/pkg/noun/platform/linux/rsignal.h @@ -9,5 +9,6 @@ #define rsignal_install_handler signal #define rsignal_deinstall_handler(sig) signal((sig), SIG_IGN) #define rsignal_setitimer setitimer +#define rsignal_getitimer getitimer #endif /* ifndef NOUN_PLATFORM_LINUX_RSIGNAL_H */ From c7ceca4f1dfb4c01749f6d53106c4998b308c56f Mon Sep 17 00:00:00 2001 From: Sigilante Date: Tue, 1 Oct 2024 16:36:53 -0500 Subject: [PATCH 6/7] WIP have time working correctly now --- pkg/noun/manage.c | 40 +++++++++++++++++----------------------- pkg/noun/nock.c | 11 +++++------ 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/pkg/noun/manage.c b/pkg/noun/manage.c index 838b50daf2..79d541ecf1 100644 --- a/pkg/noun/manage.c +++ b/pkg/noun/manage.c @@ -201,6 +201,7 @@ _cm_signal_handle_intr(int x) static void _cm_signal_handle_alrm(int x) { + stk_u->top = (timer*)NULL; // clear the timer stack _cm_signal_handle(c3__alrm); } @@ -451,19 +452,16 @@ u3m_timer_clear() void u3m_timer_push(c3_w mil_w) { - fprintf(stderr, "pushing timer %d\n", mil_w); // get the request timer interval struct itimerval itm_u; timerclear(&itm_u.it_interval); itm_u.it_value.tv_sec = (mil_w / 1000); itm_u.it_value.tv_usec = 1000 * (mil_w % 1000); - fprintf(stderr, "interval: %d s %d us\n", itm_u.it_value.tv_sec, itm_u.it_value.tv_usec); + + fprintf(stderr, "pushing timer for %u ms at %lx\r\n", mil_w, (c3_d)stk_u->top); // does the stack have anything on it? if it's clean, this is easy: - fprintf(stderr, "checking stack\n"); - fprintf(stderr, "checking stack %x\n", stk_u->top); if (stk_u->top == NULL) { - fprintf(stderr, "no timer on stack\n"); // if not, set the timer and return if ( rsignal_setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) { u3l_log("loom: push timer failed %s", strerror(errno)); @@ -473,11 +471,7 @@ u3m_timer_push(c3_w mil_w) struct timeval tim_u; gettimeofday(&tim_u, 0); - // debugging, TODO remove - c3_d tim_d = 1000000ULL * tim_u.tv_sec + tim_u.tv_usec; - fprintf(stderr, "expiry: %lx us\n", tim_d); - - struct timer* new_u = (timer*)u3a_malloc(sizeof(timer)); + struct timer* new_u = (timer*)c3_malloc(sizeof(timer)); new_u->wal_u = tim_u; new_u->nex_u = stk_u->top; stk_u->top = new_u; @@ -492,7 +486,7 @@ u3m_timer_push(c3_w mil_w) rsignal_getitimer(ITIMER_VIRTUAL, &cur_u); // zero if no timer is set - fprintf(stderr, "current interval: %d s %d us\n", cur_u.it_value.tv_sec, cur_u.it_value.tv_usec); + fprintf(stderr, "current interval: %d s %d us\r\n", cur_u.it_value.tv_sec, cur_u.it_value.tv_usec); if (timercmp(&cur_u.it_value, &itm_u.it_value, <)) { u3l_log("loom: nest timer failed, too large for remaining time %s", @@ -501,7 +495,6 @@ u3m_timer_push(c3_w mil_w) // otherwise set the timer struct itimerval rem_u; - timersub(&cur_u.it_value, &itm_u.it_value, &rem_u.it_value); if ( rsignal_setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) { @@ -514,9 +507,9 @@ u3m_timer_push(c3_w mil_w) // debugging, TODO remove c3_d tim_d = 1000000ULL * tim_u.tv_sec + tim_u.tv_usec; - fprintf(stderr, "expiry: %lx us\n", tim_d); + fprintf(stderr, "expiry: %lx us\r\n", tim_d); c3_d cur_d = cur_u.it_value.tv_sec * 1000 + cur_u.it_value.tv_usec / 1000; - fprintf(stderr, "remaining: %lx ms\n", cur_d); + fprintf(stderr, "remaining: %lx ms\r\n", cur_d); struct timer* new_u = (timer*)u3a_malloc(sizeof(timer)); new_u->wal_u = __add_itimer(tim_u, cur_u); @@ -532,17 +525,18 @@ u3m_timer_push(c3_w mil_w) void u3m_timer_pop() { + fprintf(stderr, "popping timer at %lx\r\n", (c3_d)stk_u->top); if (stk_u->top == NULL) { - u3l_log("loom: no \%jinx timer to pop"); + u3m_timer_clear(); + return; } + + // if (stk_u->top == NULL) { + // u3l_log("loom: no \%jinx timer to pop"); + // } else { timer *old_u = stk_u->top; - stk_u->top = stk_u->top->nex_u; - - if (stk_u->top == NULL) { - u3m_timer_clear(); - return; - } + stk_u->top = old_u->nex_u; struct timeval nex_u = stk_u->top->wal_u; struct timeval tim_u; @@ -2256,8 +2250,8 @@ u3m_init(size_t len_i) // start %jinx timer stack // - fprintf(stderr, "jinx: start\r\n"); - // stk_u->top = (timer*)NULL; + stk_u = (struct timer_stack*)c3_malloc(sizeof(struct timer_stack)); + stk_u->top = (timer*)NULL; } extern void u3je_secp_stop(void); diff --git a/pkg/noun/nock.c b/pkg/noun/nock.c index 5ac0a712aa..dc4f64159a 100644 --- a/pkg/noun/nock.c +++ b/pkg/noun/nock.c @@ -1930,12 +1930,11 @@ _n_hint_fore(u3_cell hin, u3_noun bus, u3_noun* clu) case c3__jinx: { if (c3y == u3a_is_atom(*clu)) { // clu is in Urbit time, but we need Unix time - c3_d tim_d; - if ( c3y == u3r_safe_chub(*clu, &tim_d) ) { - c3_w mil_w = u3_time_msc_out(tim_d); - fprintf(stderr, "u3t_jinx_time 2: %lld -> %u\n", tim_d, mil_w); - // u3m_timer_push(mil_w); - } + c3_d tim_d[2]; + u3r_chubs(0, 2, &tim_d, *clu); + c3_w sec_w = tim_d[1]; + c3_w mil_w = u3_time_msc_out(tim_d[0]); + u3m_timer_push(sec_w * 1000 + mil_w); } u3z(*clu); *clu = c3__jinx; From b9927acbf58c451927b8678ae7eb32c3e8bf2630 Mon Sep 17 00:00:00 2001 From: Sigilante Date: Wed, 2 Oct 2024 15:30:45 -0500 Subject: [PATCH 7/7] Post basically working version with printf debugging preserved. --- pkg/noun/manage.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/pkg/noun/manage.c b/pkg/noun/manage.c index 79d541ecf1..8da667d060 100644 --- a/pkg/noun/manage.c +++ b/pkg/noun/manage.c @@ -202,6 +202,7 @@ static void _cm_signal_handle_alrm(int x) { stk_u->top = (timer*)NULL; // clear the timer stack + u3l_log("\%jinx timer expired\r\n"); _cm_signal_handle(c3__alrm); } @@ -458,7 +459,7 @@ u3m_timer_push(c3_w mil_w) itm_u.it_value.tv_sec = (mil_w / 1000); itm_u.it_value.tv_usec = 1000 * (mil_w % 1000); - fprintf(stderr, "pushing timer for %u ms at %lx\r\n", mil_w, (c3_d)stk_u->top); + fprintf(stderr, "\r\npushing timer for %lu ms at 0x%lx\r\n", mil_w, (c3_d)stk_u->top); // does the stack have anything on it? if it's clean, this is easy: if (stk_u->top == NULL) { @@ -475,6 +476,7 @@ u3m_timer_push(c3_w mil_w) new_u->wal_u = tim_u; new_u->nex_u = stk_u->top; stk_u->top = new_u; + fprintf(stderr, "\r\npushed timer for %lu ms at 0x%lx\r\n", tim_u.tv_sec*1000+tim_u.tv_usec, (c3_d)stk_u->top); rsignal_install_handler(SIGVTALRM, _cm_signal_handle_alrm); } @@ -484,13 +486,14 @@ u3m_timer_push(c3_w mil_w) // check that it is less than the current remaining interval struct itimerval cur_u; + // if no timer is set this is zero but we shouldn't be here if that's the case rsignal_getitimer(ITIMER_VIRTUAL, &cur_u); - // zero if no timer is set fprintf(stderr, "current interval: %d s %d us\r\n", cur_u.it_value.tv_sec, cur_u.it_value.tv_usec); if (timercmp(&cur_u.it_value, &itm_u.it_value, <)) { u3l_log("loom: nest timer failed, too large for remaining time %s", strerror(errno)); + return; } // otherwise set the timer @@ -507,9 +510,9 @@ u3m_timer_push(c3_w mil_w) // debugging, TODO remove c3_d tim_d = 1000000ULL * tim_u.tv_sec + tim_u.tv_usec; - fprintf(stderr, "expiry: %lx us\r\n", tim_d); + fprintf(stderr, "expiry: %lu us\r\n", tim_d); c3_d cur_d = cur_u.it_value.tv_sec * 1000 + cur_u.it_value.tv_usec / 1000; - fprintf(stderr, "remaining: %lx ms\r\n", cur_d); + fprintf(stderr, "remaining: %lu ms\r\n", cur_d); struct timer* new_u = (timer*)u3a_malloc(sizeof(timer)); new_u->wal_u = __add_itimer(tim_u, cur_u); @@ -525,24 +528,28 @@ u3m_timer_push(c3_w mil_w) void u3m_timer_pop() { - fprintf(stderr, "popping timer at %lx\r\n", (c3_d)stk_u->top); + fprintf(stderr, "popping timer at 0x%lx\r\n", (c3_d)stk_u->top); if (stk_u->top == NULL) { u3m_timer_clear(); return; } - - // if (stk_u->top == NULL) { - // u3l_log("loom: no \%jinx timer to pop"); - // } else { timer *old_u = stk_u->top; stk_u->top = old_u->nex_u; + if (stk_u->top == NULL) { + // if the stack is empty, simply clear the timer + fprintf(stderr, "no more timers to pop\r\n"); + u3m_timer_clear(); + c3_free(old_u); + return; + } struct timeval nex_u = stk_u->top->wal_u; struct timeval tim_u; gettimeofday(&tim_u, 0); struct itimerval itm_u; - itm_u = __get_interval(tim_u, nex_u); + itm_u = __get_interval(nex_u, tim_u); + fprintf(stderr, "remaining interval: %d s %d us\r\n", itm_u.it_value.tv_sec, itm_u.it_value.tv_usec); if ( rsignal_setitimer(ITIMER_VIRTUAL, &itm_u, 0) ) { u3l_log("loom: pop timer failed %s", strerror(errno)); @@ -551,7 +558,7 @@ u3m_timer_pop() rsignal_install_handler(SIGVTALRM, _cm_signal_handle_alrm); } - free(old_u); + c3_free(old_u); } }