From fa576b00d7112717062b58c38000c512e9566919 Mon Sep 17 00:00:00 2001 From: Benjamin Summers Date: Mon, 12 Nov 2018 12:20:32 -0800 Subject: [PATCH] Implemented u3t_boff for Linux. --- noun/trace.c | 88 +++++++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 53 deletions(-) diff --git a/noun/trace.c b/noun/trace.c index a482b2e107..0fbe833243 100644 --- a/noun/trace.c +++ b/noun/trace.c @@ -388,58 +388,34 @@ u3t_boot(void) { if ( u3C.wag_w & u3o_debug_cpu ) { _ct_lop_o = c3n; -#if defined(U3_OS_osx) -#if 1 +#if defined(U3_OS_osx) || defined(U3_OS_linux) + // Register _ct_sigaction to be called on `SIGPROF`. { - struct itimerval itm_v; - struct sigaction sig_s; - sigset_t set; - - sig_s.__sigaction_u.__sa_handler = _ct_sigaction; - sig_s.sa_mask = 0; - sig_s.sa_flags = 0; - sigaction(SIGPROF, &sig_s, 0); - - sigemptyset(&set); - sigaddset(&set, SIGPROF); - if ( 0 != pthread_sigmask(SIG_UNBLOCK, &set, NULL) ) { - perror("pthread_sigmask"); - } - - itm_v.it_interval.tv_sec = 0; - itm_v.it_interval.tv_usec = 10000; - // itm_v.it_interval.tv_usec = 100000; - itm_v.it_value = itm_v.it_interval; - - setitimer(ITIMER_PROF, &itm_v, 0); - } -#endif -#elif defined(U3_OS_linux) - { - struct itimerval itm_v; - struct sigaction sig_s; - sigset_t set; - + struct sigaction sig_s = {0}; sig_s.sa_handler = _ct_sigaction; sigemptyset(&(sig_s.sa_mask)); - sig_s.sa_flags = 0; sigaction(SIGPROF, &sig_s, 0); + } + // Unblock `SIGPROF` for this thread (we will block it again when `u3t_boff` is called). + { + sigset_t set; sigemptyset(&set); sigaddset(&set, SIGPROF); if ( 0 != pthread_sigmask(SIG_UNBLOCK, &set, NULL) ) { perror("pthread_sigmask"); } + } - itm_v.it_interval.tv_sec = 0; + // Ask for SIGPROF to be sent every 10ms. + { + struct itimerval itm_v = {0}; itm_v.it_interval.tv_usec = 10000; - // itm_v.it_interval.tv_usec = 100000; itm_v.it_value = itm_v.it_interval; - setitimer(ITIMER_PROF, &itm_v, 0); } #elif defined(U3_OS_bsd) - // TODO: support profiling on bsd +# error "Profiling isn't yet supported on BSD" #else # error "port: profiling" #endif @@ -452,28 +428,34 @@ void u3t_boff(void) { if ( u3C.wag_w & u3o_debug_cpu ) { -#if defined(U3_OS_osx) - struct sigaction sig_s; - struct itimerval itm_v; - sigset_t set; - - sigemptyset(&set); - sigaddset(&set, SIGPROF); - if ( 0 != pthread_sigmask(SIG_BLOCK, &set, NULL) ) { - perror("pthread_sigmask"); +#if defined(U3_OS_osx) || defined(U3_OS_linux) + // Mask SIGPROF signals in this thread (and this is the only + // thread that unblocked them). + { + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGPROF); + if ( 0 != pthread_sigmask(SIG_BLOCK, &set, NULL) ) { + perror("pthread_sigmask"); + } } - itm_v.it_interval.tv_sec = 0; - itm_v.it_interval.tv_usec = 0; - itm_v.it_value = itm_v.it_interval; + // Disable the SIGPROF timer. + { + struct itimerval itm_v = {0}; + setitimer(ITIMER_PROF, &itm_v, 0); + } - setitimer(ITIMER_PROF, &itm_v, 0); - sigaction(SIGPROF, &sig_s, 0); + // Ignore SIGPROF signals. + { + struct sigaction sig_s = {0}; + sigemptyset(&(sig_s.sa_mask)); + sig_s.sa_handler = SIG_IGN; + sigaction(SIGPROF, &sig_s, 0); + } -#elif defined(U3_OS_linux) - // TODO: support profiling on linux #elif defined(U3_OS_bsd) - // TODO: support profiling on bsd +# error "Profiling isn't yet supported on BSD" #else # error "port: profiling" #endif