noun, worker: write -P profile into pier

The -P argument makes urbit send itself SIGPROF every 10ms. Sample
profile data is interpolated into a structure on the home road, which is
summarized and printed when urbit exits gracefully. (Note that this
profile will be useless without the CPU_DEBUG build option).

As of v0.8.0, the profiling became much more awkward. The multi-process
shutdown doesn't include affordances for sending the profiling data over
IPC, so it just prints to the terminal after urbit appears to have
shutdown. This PR changes the profiling printout, unconditionally
writing it to a file in the pier (at .urb/put/profile/~DATE.txt).
This commit is contained in:
Joe Bryan 2019-09-05 23:42:05 -07:00 committed by Jared Tobin
parent d7f9d9aefc
commit a124dfe61f
No known key found for this signature in database
GPG Key ID: 0E4647D58F8A69E4
3 changed files with 43 additions and 12 deletions

View File

@ -112,7 +112,7 @@
/* u3t_damp(): print and clear profile data.
*/
void
u3t_damp(void);
u3t_damp(FILE* fil_u);
/* u3t_boff(): turn profile sampling off.
*/

View File

@ -425,8 +425,10 @@ u3t_event_trace(const c3_c* name, c3_c type)
/* u3t_print_steps: print step counter.
*/
void
u3t_print_steps(c3_c* cap_c, c3_d sep_d)
u3t_print_steps(FILE* fil_u, c3_c* cap_c, c3_d sep_d)
{
c3_assert( 0 != fil_u );
c3_w gib_w = (sep_d / 1000000000ULL);
c3_w mib_w = (sep_d % 1000000000ULL) / 1000000ULL;
c3_w kib_w = (sep_d % 1000000ULL) / 1000ULL;
@ -436,17 +438,17 @@ u3t_print_steps(c3_c* cap_c, c3_d sep_d)
//
if ( sep_d ) {
if ( gib_w ) {
fprintf(stderr, "%s: G/%d.%03d.%03d.%03d\r\n",
fprintf(fil_u, "%s: G/%d.%03d.%03d.%03d\r\n",
cap_c, gib_w, mib_w, kib_w, bib_w);
}
else if ( mib_w ) {
fprintf(stderr, "%s: M/%d.%03d.%03d\r\n", cap_c, mib_w, kib_w, bib_w);
fprintf(fil_u, "%s: M/%d.%03d.%03d\r\n", cap_c, mib_w, kib_w, bib_w);
}
else if ( kib_w ) {
fprintf(stderr, "%s: K/%d.%03d\r\n", cap_c, kib_w, bib_w);
fprintf(fil_u, "%s: K/%d.%03d\r\n", cap_c, kib_w, bib_w);
}
else if ( bib_w ) {
fprintf(stderr, "%s: %d\r\n", cap_c, bib_w);
fprintf(fil_u, "%s: %d\r\n", cap_c, bib_w);
}
}
}
@ -454,8 +456,10 @@ u3t_print_steps(c3_c* cap_c, c3_d sep_d)
/* u3t_damp(): print and clear profile data.
*/
void
u3t_damp(void)
u3t_damp(FILE* fil_u)
{
c3_assert( 0 != fil_u );
if ( 0 != u3R->pro.day ) {
u3_noun wol = u3do("pi-tell", u3R->pro.day);
@ -466,10 +470,10 @@ u3t_damp(void)
while ( u3_nul != low ) {
c3_c* str_c = (c3_c*)u3r_tape(u3h(low));
fputs(str_c, fil_u);
fputs("\r\n", fil_u);
fprintf(stderr, "%s\r\n", str_c);
c3_free(str_c);
low = u3t(low);
}
@ -481,8 +485,8 @@ u3t_damp(void)
u3R->pro.day = u3nt(u3nq(0, 0, 0, u3nq(0, 0, 0, 0)), 0, 0);
}
u3t_print_steps("nocks", u3R->pro.nox_d);
u3t_print_steps("cells", u3R->pro.cel_d);
u3t_print_steps(fil_u, "nocks", u3R->pro.nox_d);
u3t_print_steps(fil_u, "cells", u3R->pro.cel_d);
u3R->pro.nox_d = 0;
u3R->pro.cel_d = 0;

View File

@ -692,7 +692,34 @@ static void
_worker_poke_exit(c3_w cod_w) // exit code
{
if ( u3C.wag_w & u3o_debug_cpu ) {
u3t_damp();
FILE* fil_u;
{
u3_noun wen = u3dc("scot", c3__da, u3k(u3A->now));
c3_c* wen_c = u3r_string(wen);
c3_c nam_c[2048];
snprintf(nam_c, 2048, "%s/.urb/put/profile", u3P.dir_c);
struct stat st;
if ( -1 == stat(nam_c, &st) ) {
mkdir(nam_c, 0700);
}
c3_c man_c[2048];
snprintf(man_c, 2048, "%s/%s.txt", nam_c, wen_c);
fil_u = fopen(man_c, "w");
free(wen_c);
u3z(wen);
}
u3t_damp(fil_u);
{
fclose(fil_u);
}
}
exit(cod_w);