chore: cleanup softint

sledge_graph
Sean McBride 5 years ago
parent d979a74986
commit 7da1f4a284

@ -151,7 +151,7 @@ static inline void
switch_to_sandbox(struct sandbox *next_sandbox) switch_to_sandbox(struct sandbox *next_sandbox)
{ {
arch_context_t *next_register_context = next_sandbox == NULL ? NULL : &next_sandbox->ctxt; arch_context_t *next_register_context = next_sandbox == NULL ? NULL : &next_sandbox->ctxt;
softint_disable(); softint__disable();
struct sandbox *current_sandbox = get_current_sandbox(); struct sandbox *current_sandbox = get_current_sandbox();
arch_context_t *current_register_context = current_sandbox == NULL ? NULL : &current_sandbox->ctxt; arch_context_t *current_register_context = current_sandbox == NULL ? NULL : &current_sandbox->ctxt;
set_current_sandbox(next_sandbox); set_current_sandbox(next_sandbox);
@ -159,7 +159,7 @@ switch_to_sandbox(struct sandbox *next_sandbox)
if (current_sandbox && current_sandbox->state == RETURNED) add_sandbox_to_completion_queue(current_sandbox); if (current_sandbox && current_sandbox->state == RETURNED) add_sandbox_to_completion_queue(current_sandbox);
next_context = next_register_context; next_context = next_register_context;
arch_context_switch(current_register_context, next_register_context); arch_context_switch(current_register_context, next_register_context);
softint_enable(); softint__enable();
} }
/** /**

@ -5,8 +5,37 @@
#include <assert.h> #include <assert.h>
#include <signal.h> #include <signal.h>
/***************************************
* Externs
***************************************/
extern __thread volatile sig_atomic_t softint_off;
/***************************************
* Public Static Inlines
***************************************/
static inline void
softint__disable(void)
{
while (__sync_bool_compare_and_swap(&softint_off, 0, 1) == false)
;
}
static inline void
softint__enable(void)
{
if (__sync_bool_compare_and_swap(&softint_off, 1, 0) == false) assert(0);
}
static inline int
softint__is_enabled(void)
{
return (softint_off == 0);
}
static inline int static inline int
softint_mask(int signal) softint__mask(int signal)
{ {
sigset_t set; sigset_t set;
int return_code; int return_code;
@ -26,7 +55,7 @@ softint_mask(int signal)
} }
static inline int static inline int
softint_unmask(int signal) softint__unmask(int signal)
{ {
sigset_t set; sigset_t set;
int return_code; int return_code;
@ -45,30 +74,12 @@ softint_unmask(int signal)
return 0; return 0;
} }
extern __thread volatile sig_atomic_t softint_off; /***************************************
* Exports from module.c
static inline void ***************************************/
softint_disable(void)
{
while (__sync_bool_compare_and_swap(&softint_off, 0, 1) == false)
;
}
static inline void
softint_enable(void)
{
if (__sync_bool_compare_and_swap(&softint_off, 1, 0) == false) assert(0);
}
static inline int
softint_enabled(void)
{
return (softint_off == 0);
}
void softint_init(void);
void softint_timer_arm(void); void softint__initialize(void);
void softint_timer_disarm(void); void softint__arm_timer(void);
void softint__disarm_timer(void);
#endif /* SFRT_SOFTINT_H */ #endif /* SFRT_SOFTINT_H */

@ -43,8 +43,8 @@ initialize_runtime(void)
deque_init_sandbox(global_deque, SBOX_MAX_REQS); deque_init_sandbox(global_deque, SBOX_MAX_REQS);
// Mask Signals // Mask Signals
softint_mask(SIGUSR1); softint__mask(SIGUSR1);
softint_mask(SIGALRM); softint__mask(SIGALRM);
// Initialize http_parser_settings global // Initialize http_parser_settings global
http_parser_settings__initialize(&global__http_parser_settings); http_parser_settings__initialize(&global__http_parser_settings);
@ -129,8 +129,8 @@ initialize_listener_thread(void)
ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs); ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs);
assert(ret == 0); assert(ret == 0);
softint_init(); softint__initialize();
softint_timer_arm(); softint__arm_timer();
} }
/*************************** /***************************
@ -169,7 +169,7 @@ static inline void add_sandbox_to_local_run_queue(struct sandbox *sandbox);
void void
wakeup_sandbox(sandbox_t *sandbox) wakeup_sandbox(sandbox_t *sandbox)
{ {
softint_disable(); softint__disable();
debuglog("[%p: %s]\n", sandbox, sandbox->module->name); debuglog("[%p: %s]\n", sandbox, sandbox->module->name);
if (sandbox->state != BLOCKED) goto done; if (sandbox->state != BLOCKED) goto done;
assert(sandbox->state == BLOCKED); assert(sandbox->state == BLOCKED);
@ -177,7 +177,7 @@ wakeup_sandbox(sandbox_t *sandbox)
sandbox->state = RUNNABLE; sandbox->state = RUNNABLE;
ps_list_head_append_d(&local_run_queue, sandbox); ps_list_head_append_d(&local_run_queue, sandbox);
done: done:
softint_enable(); softint__enable();
} }
@ -188,13 +188,13 @@ void
block_current_sandbox(void) block_current_sandbox(void)
{ {
assert(in_callback == 0); assert(in_callback == 0);
softint_disable(); softint__disable();
struct sandbox *current_sandbox = get_current_sandbox(); struct sandbox *current_sandbox = get_current_sandbox();
ps_list_rem_d(current_sandbox); ps_list_rem_d(current_sandbox);
current_sandbox->state = BLOCKED; current_sandbox->state = BLOCKED;
struct sandbox *next_sandbox = get_next_sandbox_from_local_run_queue(0); struct sandbox *next_sandbox = get_next_sandbox_from_local_run_queue(0);
debuglog("[%p: %next_sandbox, %p: %next_sandbox]\n", current_sandbox, current_sandbox->module->name, next_sandbox, next_sandbox ? next_sandbox->module->name : ""); debuglog("[%p: %next_sandbox, %p: %next_sandbox]\n", current_sandbox, current_sandbox->module->name, next_sandbox, next_sandbox ? next_sandbox->module->name : "");
softint_enable(); softint__enable();
switch_to_sandbox(next_sandbox); switch_to_sandbox(next_sandbox);
} }
@ -373,9 +373,9 @@ worker_thread_single_loop(void)
if (!in_callback) execute_libuv_event_loop(); if (!in_callback) execute_libuv_event_loop();
// Get and return the sandbox at the head of the thread local runqueue // Get and return the sandbox at the head of the thread local runqueue
softint_disable(); softint__disable();
struct sandbox *sandbox = get_next_sandbox_from_local_run_queue(0); struct sandbox *sandbox = get_next_sandbox_from_local_run_queue(0);
softint_enable(); softint__enable();
assert(sandbox == NULL || sandbox->state == RUNNABLE); assert(sandbox == NULL || sandbox->state == RUNNABLE);
return sandbox; return sandbox;
} }
@ -395,8 +395,8 @@ worker_thread_main(void *return_code)
softint_off = 0; softint_off = 0;
next_context = NULL; next_context = NULL;
#ifndef PREEMPT_DISABLE #ifndef PREEMPT_DISABLE
softint_unmask(SIGALRM); softint__unmask(SIGALRM);
softint_unmask(SIGUSR1); softint__unmask(SIGUSR1);
#endif #endif
uv_loop_init(&uvio_handle); uv_loop_init(&uvio_handle);
in_callback = 0; in_callback = 0;
@ -426,13 +426,13 @@ exit_current_sandbox(void)
{ {
struct sandbox *current_sandbox = get_current_sandbox(); struct sandbox *current_sandbox = get_current_sandbox();
assert(current_sandbox); assert(current_sandbox);
softint_disable(); softint__disable();
remove_sandbox_from_local_run_queue(current_sandbox); remove_sandbox_from_local_run_queue(current_sandbox);
current_sandbox->state = RETURNED; current_sandbox->state = RETURNED;
struct sandbox *next_sandbox = get_next_sandbox_from_local_run_queue(0); struct sandbox *next_sandbox = get_next_sandbox_from_local_run_queue(0);
assert(next_sandbox != current_sandbox); assert(next_sandbox != current_sandbox);
softint_enable(); softint__enable();
// free resources from "main function execution", as stack still in use. // free resources from "main function execution", as stack still in use.
// unmap linear memory only! // unmap linear memory only!
munmap(current_sandbox->linear_memory_start, SBOX_MAX_MEM + PAGE_SIZE); munmap(current_sandbox->linear_memory_start, SBOX_MAX_MEM + PAGE_SIZE);

@ -277,10 +277,10 @@ sandbox_main(void)
// FIXME: is this right? this is the first time this sandbox is running.. so it wont // FIXME: is this right? this is the first time this sandbox is running.. so it wont
// return to switch_to_sandbox() api.. // return to switch_to_sandbox() api..
// we'd potentially do what we'd in switch_to_sandbox() api here for cleanup.. // we'd potentially do what we'd in switch_to_sandbox() api here for cleanup..
if (!softint_enabled()) { if (!softint__is_enabled()) {
arch_context_init(&current_sandbox->ctxt, 0, 0); arch_context_init(&current_sandbox->ctxt, 0, 0);
next_context = NULL; next_context = NULL;
softint_enable(); softint__enable();
} }
struct module *current_module = get_sandbox_module(current_sandbox); struct module *current_module = get_sandbox_module(current_sandbox);
int argument_count = module__get_argument_count(current_module); int argument_count = module__get_argument_count(current_module);

@ -13,91 +13,32 @@
#include <arch/context.h> #include <arch/context.h>
#include <softint.h> #include <softint.h>
__thread static volatile sig_atomic_t SIGALRM_count = 0; /***************************************
__thread static volatile sig_atomic_t SIGUSR_count = 0; * Process Globals
***************************************/
__thread volatile sig_atomic_t softint_off = 0;
static const int softints[] = { SIGALRM, SIGUSR1 }; static const int softints[] = { SIGALRM, SIGUSR1 };
/** /***************************************
* Arms the Interval Timer to start in 10ms and then trigger a SIGALRM every 5ms * Thread Globals
**/ ***************************************/
void
softint_timer_arm(void)
{
#ifndef PREEMPT_DISABLE
struct itimerval interval_timer;
memset(&interval_timer, 0, sizeof(struct itimerval));
interval_timer.it_value.tv_usec = SOFTINT_TIMER_START_USEC;
interval_timer.it_interval.tv_usec = SOFTINT_TIMER_PERIOD_USEC;
int return_code = setitimer(ITIMER_REAL, &interval_timer, NULL);
if (return_code) {
perror("setitimer");
exit(1);
}
#endif
}
/**
* Disarm the Interval Timer
**/
void
softint_timer_disarm(void)
{
struct itimerval interval_timer;
memset(&interval_timer, 0, sizeof(struct itimerval));
interval_timer.it_value.tv_sec = 0;
interval_timer.it_interval.tv_usec = 0;
int return_code = setitimer(ITIMER_REAL, &interval_timer, NULL);
if (return_code) {
perror("setitimer");
exit(1);
}
}
/**
* Preempt the current sandbox and start executing the next sandbox
* @param user_context_raw void* to a user_context struct
**/
static inline void
softint_alarm_schedule(void *user_context_raw)
{
softint_disable(); // no nesting!
struct sandbox *curr = get_current_sandbox(); __thread static volatile sig_atomic_t SIGALRM_count = 0;
ucontext_t * user_context = (ucontext_t *)user_context_raw; __thread static volatile sig_atomic_t SIGUSR_count = 0;
__thread volatile sig_atomic_t softint_off = 0;
// no sandboxes running..so nothing to preempt..let the "main" scheduler run its course.
if (curr == NULL) goto done;
// find a next sandbox to run..
struct sandbox *next = get_next_sandbox_from_local_run_queue(1);
if (next == NULL) goto done;
if (next == curr) goto done; // only this sandbox to schedule.. return to it!
// save the current sandbox, state from user_context!
arch_mcontext_save(&curr->ctxt, &user_context->uc_mcontext);
// set_current_sandbox on it. restore through *user_context.. /***************************************
set_current_sandbox(next); * Externs
***************************************/
if (arch_mcontext_restore(&user_context->uc_mcontext, &next->ctxt)) goto skip; extern pthread_t worker_threads[];
// reset if SIGALRM happens before SIGUSR1 and if don't preempt..OR
// perhaps switch here for SIGUSR1 and see if we can clear that signal
// so it doesn't get called on SIGALRM return..
// next_context = NULL;
done: /***************************************
softint_enable(); * Private Static Inlines
skip: ***************************************/
return;
}
extern pthread_t worker_threads[]; static inline void softint__handle_signals(int signal_type, siginfo_t *signal_info, void *user_context_raw);
static inline void softint__schedule_alarm(void *user_context_raw);
/** /**
* The handler function for Software Interrupts (signals) * The handler function for Software Interrupts (signals)
@ -108,7 +49,7 @@ extern pthread_t worker_threads[];
* @param user_context_raw void* to a user_context struct * @param user_context_raw void* to a user_context struct
**/ **/
static inline void static inline void
softint_handler(int signal_type, siginfo_t *signal_info, void *user_context_raw) softint__handle_signals(int signal_type, siginfo_t *signal_info, void *user_context_raw)
{ {
#ifdef PREEMPT_DISABLE #ifdef PREEMPT_DISABLE
assert(0); assert(0);
@ -139,14 +80,14 @@ softint_handler(int signal_type, siginfo_t *signal_info, void *user_context_raw)
// softints per-core.. // softints per-core..
if (curr && curr->state == RETURNED) return; if (curr && curr->state == RETURNED) return;
if (next_context) return; if (next_context) return;
if (!softint_enabled()) return; if (!softint__is_enabled()) return;
softint_alarm_schedule(user_context_raw); softint__schedule_alarm(user_context_raw);
break; break;
} }
case SIGUSR1: { case SIGUSR1: {
// make sure sigalrm doesn't mess this up if nested.. // make sure sigalrm doesn't mess this up if nested..
assert(!softint_enabled()); assert(!softint__is_enabled());
/* we set current before calling pthread_kill! */ /* we set current before calling pthread_kill! */
assert(next_context && (&curr->ctxt == next_context)); assert(next_context && (&curr->ctxt == next_context));
assert(signal_info->si_code == SI_TKILL); assert(signal_info->si_code == SI_TKILL);
@ -159,7 +100,7 @@ softint_handler(int signal_type, siginfo_t *signal_info, void *user_context_raw)
// memcpy from next context.. // memcpy from next context..
arch_mcontext_restore(&user_context->uc_mcontext, &curr->ctxt); arch_mcontext_restore(&user_context->uc_mcontext, &curr->ctxt);
next_context = NULL; next_context = NULL;
softint_enable(); softint__enable();
break; break;
} }
default: default:
@ -168,16 +109,99 @@ softint_handler(int signal_type, siginfo_t *signal_info, void *user_context_raw)
#endif #endif
} }
/**
* Preempt the current sandbox and start executing the next sandbox
* @param user_context_raw void* to a user_context struct
**/
static inline void
softint__schedule_alarm(void *user_context_raw)
{
softint__disable(); // no nesting!
struct sandbox *curr = get_current_sandbox();
ucontext_t * user_context = (ucontext_t *)user_context_raw;
// no sandboxes running..so nothing to preempt..let the "main" scheduler run its course.
if (curr == NULL) goto done;
// find a next sandbox to run..
struct sandbox *next = get_next_sandbox_from_local_run_queue(1);
if (next == NULL) goto done;
if (next == curr) goto done; // only this sandbox to schedule.. return to it!
// save the current sandbox, state from user_context!
arch_mcontext_save(&curr->ctxt, &user_context->uc_mcontext);
// set_current_sandbox on it. restore through *user_context..
set_current_sandbox(next);
if (arch_mcontext_restore(&user_context->uc_mcontext, &next->ctxt)) goto skip;
// reset if SIGALRM happens before SIGUSR1 and if don't preempt..OR
// perhaps switch here for SIGUSR1 and see if we can clear that signal
// so it doesn't get called on SIGALRM return..
// next_context = NULL;
done:
softint__enable();
skip:
return;
}
/***************************************
* Public Functions
***************************************/
/**
* Arms the Interval Timer to start in 10ms and then trigger a SIGALRM every 5ms
**/
void
softint__arm_timer(void)
{
#ifndef PREEMPT_DISABLE
struct itimerval interval_timer;
memset(&interval_timer, 0, sizeof(struct itimerval));
interval_timer.it_value.tv_usec = SOFTINT_TIMER_START_USEC;
interval_timer.it_interval.tv_usec = SOFTINT_TIMER_PERIOD_USEC;
int return_code = setitimer(ITIMER_REAL, &interval_timer, NULL);
if (return_code) {
perror("setitimer");
exit(1);
}
#endif
}
/**
* Disarm the Interval Timer
**/
void
softint__disarm_timer(void)
{
struct itimerval interval_timer;
memset(&interval_timer, 0, sizeof(struct itimerval));
interval_timer.it_value.tv_sec = 0;
interval_timer.it_interval.tv_usec = 0;
int return_code = setitimer(ITIMER_REAL, &interval_timer, NULL);
if (return_code) {
perror("setitimer");
exit(1);
}
}
/** /**
* Initialize software Interrupts * Initialize software Interrupts
* Register sonftint_handler to execute on SIGALRM and SIGUSR1 * Register sonftint_handler to execute on SIGALRM and SIGUSR1
**/ **/
void void
softint_init(void) softint__initialize(void)
{ {
struct sigaction signal_action; struct sigaction signal_action;
memset(&signal_action, 0, sizeof(struct sigaction)); memset(&signal_action, 0, sizeof(struct sigaction));
signal_action.sa_sigaction = softint_handler; signal_action.sa_sigaction = softint__handle_signals;
signal_action.sa_flags = SA_SIGINFO | SA_RESTART; signal_action.sa_flags = SA_SIGINFO | SA_RESTART;
for (int i = 0; i < (sizeof(softints) / sizeof(softints[0])); i++) { for (int i = 0; i < (sizeof(softints) / sizeof(softints[0])); i++) {

Loading…
Cancel
Save