@ -9,6 +9,7 @@
# include <threads.h>
# include <threads.h>
# include <unistd.h>
# include <unistd.h>
# include <ucontext.h>
# include <ucontext.h>
# include <inttypes.h>
# include "arch/context.h"
# include "arch/context.h"
# include "current_sandbox.h"
# include "current_sandbox.h"
@ -25,6 +26,9 @@
# include "software_interrupt.h"
# include "software_interrupt.h"
# include "software_interrupt_counts.h"
# include "software_interrupt_counts.h"
extern uint64_t total_held [ 1024 ] ;
extern uint64_t longest_held [ 1024 ] ;
thread_local _Atomic volatile sig_atomic_t handler_depth = 0 ;
thread_local _Atomic volatile sig_atomic_t handler_depth = 0 ;
thread_local _Atomic volatile sig_atomic_t deferred_sigalrm = 0 ;
thread_local _Atomic volatile sig_atomic_t deferred_sigalrm = 0 ;
@ -33,7 +37,9 @@ thread_local _Atomic volatile sig_atomic_t deferred_sigalrm = 0;
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
extern pthread_t * runtime_worker_threads ;
extern pthread_t * runtime_worker_threads ;
extern thread_local uint32_t total_local_requests ;
extern time_t t_start ;
extern thread_local int worker_thread_idx ;
/**************************
/**************************
* Private Static Inlines *
* Private Static Inlines *
* * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * */
@ -75,6 +81,33 @@ propagate_sigalrm(siginfo_t *signal_info)
}
}
}
}
/**
* A POSIX signal is delivered to only one thread .
* This function broadcasts the sigint signal to all other worker threads
*/
static inline void
sigint_propagate_workers_listener ( siginfo_t * signal_info )
{
/* Signal was sent directly by the kernel user space, so forward to other threads */
if ( signal_info - > si_code = = SI_KERNEL | | signal_info - > si_code = = SI_USER ) {
for ( int i = 0 ; i < runtime_worker_threads_count ; i + + ) {
if ( pthread_self ( ) = = runtime_worker_threads [ i ] ) continue ;
/* All threads should have been initialized */
assert ( runtime_worker_threads [ i ] ! = 0 ) ;
pthread_kill ( runtime_worker_threads [ i ] , SIGINT ) ;
}
/* send to listener thread */
if ( pthread_self ( ) ! = listener_thread_id ) {
pthread_kill ( listener_thread_id , SIGINT ) ;
}
} else {
/* Signal forwarded from another thread. Just confirm it resulted from pthread_kill */
assert ( signal_info - > si_code = = SI_TKILL ) ;
}
}
static inline bool
static inline bool
worker_thread_is_running_cooperative_scheduler ( void )
worker_thread_is_running_cooperative_scheduler ( void )
{
{
@ -184,6 +217,22 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void
break ;
break ;
}
}
case SIGINT : {
/* Stop the alarm timer first */
software_interrupt_disarm_timer ( ) ;
sigint_propagate_workers_listener ( signal_info ) ;
/* calculate the throughput */
time_t t_end = time ( NULL ) ;
double seconds = difftime ( t_end , t_start ) ;
double throughput = atomic_load ( & sandbox_state_totals [ SANDBOX_COMPLETE ] ) / seconds ;
uint32_t total_sandboxes_error = atomic_load ( & sandbox_state_totals [ SANDBOX_ERROR ] ) ;
printf ( " throughput is %f, error request is %u global total request %d worker %d total requests is %u worker total_held % " PRIu64 " longest_held % " PRIu64 " listener total_held % " PRIu64 " longest_held % " PRIu64 " \n " ,
throughput , total_sandboxes_error , atomic_load ( & sandbox_state_totals [ SANDBOX_COMPLETE ] ) , worker_thread_idx , total_local_requests , total_held [ worker_thread_idx ] , longest_held [ worker_thread_idx ] , total_held [ 200 ] , longest_held [ 200 ] ) ;
fflush ( stdout ) ;
pthread_exit ( 0 ) ;
}
default : {
default : {
const char * signal_name = strsignal ( signal_type ) ;
const char * signal_name = strsignal ( signal_type ) ;
switch ( signal_info - > si_code ) {
switch ( signal_info - > si_code ) {
@ -268,9 +317,10 @@ software_interrupt_initialize(void)
sigaddset ( & signal_action . sa_mask , SIGUSR1 ) ;
sigaddset ( & signal_action . sa_mask , SIGUSR1 ) ;
sigaddset ( & signal_action . sa_mask , SIGFPE ) ;
sigaddset ( & signal_action . sa_mask , SIGFPE ) ;
sigaddset ( & signal_action . sa_mask , SIGSEGV ) ;
sigaddset ( & signal_action . sa_mask , SIGSEGV ) ;
sigaddset ( & signal_action . sa_mask , SIGINT ) ;
const int supported_signals [ ] = { SIGALRM , SIGUSR1 , SIGFPE , SIGSEGV } ;
const int supported_signals [ ] = { SIGALRM , SIGUSR1 , SIGFPE , SIGSEGV , SIGINT } ;
const size_t supported_signals_len = 4 ;
const size_t supported_signals_len = 5 ;
for ( int i = 0 ; i < supported_signals_len ; i + + ) {
for ( int i = 0 ; i < supported_signals_len ; i + + ) {
int signal = supported_signals [ i ] ;
int signal = supported_signals [ i ] ;