Merge pull request #201 from gwsystems/dynamic-preemption-toggle

feat: make preemption toggle runtime config
main
Sean McBride 4 years ago committed by GitHub
commit dee44afa48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -85,9 +85,6 @@ CFLAGS += -D${ARCH}
CFLAGS += -DNCORES=${TOTAL_CORES}
CFLAGS += -DPAGE_SIZE=$(PAGE_SIZE)
# Optionally Disable preemption
# CFLAGS += -DPREEMPT_DISABLE
# Sandboxes running on Sledge always use WebAssembly linear memory
CFLAGS += -DUSE_MEM_VM

@ -10,7 +10,7 @@ __common_dump_callstack() {
echo "Call Stack:"
# Skip the dump_bash_stack and error_msg_frames
for ((i = 2; i < ${#FUNCNAME[@]}; i++)); do
printf "\t%d - %s\n" "$((i - 2))" "${FUNCNAME[i]} (${BASH_SOURCE[i + 1]}:${BASH_LINENO[i]})"
printf "\t%d - %s\n" "$((i - 2))" "${FUNCNAME[i]} (${BASH_SOURCE[i + 1]}:${BASH_LINENO[i + 1]})"
done
}

@ -90,3 +90,5 @@ print_runtime_scheduler(enum RUNTIME_SCHEDULER variant)
};
extern enum RUNTIME_SCHEDULER runtime_scheduler;
extern bool runtime_preemption_enabled;
extern uint32_t runtime_quantum_us;

@ -11,9 +11,6 @@
#include "debuglog.h"
#define SOFTWARE_INTERRUPT_TIME_TO_START_IN_USEC (2 * 1000) /* 2 ms */
#define SOFTWARE_INTERRUPT_INTERVAL_DURATION_IN_USEC (1 * 1000) /* 1 ms */
/************
* Externs *
***********/

@ -40,6 +40,10 @@ FILE *runtime_sandbox_perf_log = NULL;
enum RUNTIME_SCHEDULER runtime_scheduler = RUNTIME_SCHEDULER_FIFO;
int runtime_worker_core_count;
bool runtime_preemption_enabled = true;
uint32_t runtime_quantum_us = 5000; /* 5ms */
/**
* Returns instructions on use of CLI if used incorrectly
* @param cmd - The command the user entered
@ -213,6 +217,22 @@ runtime_configure()
}
printf("\tScheduler Policy: %s\n", print_runtime_scheduler(runtime_scheduler));
/* Runtime Preemption Toggle */
char *preempt_disable = getenv("SLEDGE_DISABLE_PREEMPTION");
if (preempt_disable != NULL && strcmp(preempt_disable, "false") != 0) runtime_preemption_enabled = false;
printf("\tPreemption: %s\n", runtime_preemption_enabled ? "Enabled" : "Disabled");
/* Runtime Quantum */
char *quantum_raw = getenv("SLEDGE_QUANTUM_US");
if (quantum_raw != NULL) {
long quantum = atoi(quantum_raw);
if (unlikely(quantum <= 0)) panic("SLEDGE_QUANTUM_US must be a positive integer, saw %ld\n", quantum);
if (unlikely(quantum > 999999))
panic("SLEDGE_QUANTUM_US must be less than 999999 ms, saw %ld\n", quantum);
runtime_quantum_us = (uint32_t)quantum;
}
printf("\tQuantum: %u us\n", runtime_quantum_us);
/* Runtime Perf Log */
char *runtime_sandbox_perf_log_path = getenv("SLEDGE_SANDBOX_PERF_LOG");
if (runtime_sandbox_perf_log_path != NULL) {
@ -352,8 +372,7 @@ main(int argc, char **argv)
runtime_processor_speed_MHz = runtime_get_processor_speed_MHz();
if (unlikely(runtime_processor_speed_MHz == 0)) panic("Failed to detect processor speed\n");
software_interrupt_interval_duration_in_cycles = (uint64_t)SOFTWARE_INTERRUPT_INTERVAL_DURATION_IN_USEC
* runtime_processor_speed_MHz;
software_interrupt_interval_duration_in_cycles = (uint64_t)runtime_quantum_us * runtime_processor_speed_MHz;
printf("\tProcessor Speed: %u MHz\n", runtime_processor_speed_MHz);
runtime_set_resource_limits_to_max();

@ -165,9 +165,9 @@ software_interrupt_validate_worker()
static inline void
software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void *user_context_raw)
{
#ifdef PREEMPT_DISABLE
panic("Unexpectedly invoked signal handlers when PREEMPT_DISABLE set\n");
#else
if (unlikely(!runtime_preemption_enabled)) {
panic("Unexpectedly invoked signal handlers with preemption disabled\n");
}
software_interrupt_validate_worker();
@ -190,7 +190,6 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void
}
}
}
#endif
}
/********************
@ -198,24 +197,24 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void
*******************/
/**
* Arms the Interval Timer to start in 10ms and then trigger a SIGALRM every 5ms
* Arms the Interval Timer to start in one quantum and then trigger a SIGALRM every quantum
*/
void
software_interrupt_arm_timer(void)
{
#ifndef PREEMPT_DISABLE
if (!runtime_preemption_enabled) return;
struct itimerval interval_timer;
memset(&interval_timer, 0, sizeof(struct itimerval));
interval_timer.it_value.tv_usec = SOFTWARE_INTERRUPT_TIME_TO_START_IN_USEC;
interval_timer.it_interval.tv_usec = SOFTWARE_INTERRUPT_INTERVAL_DURATION_IN_USEC;
interval_timer.it_value.tv_usec = runtime_quantum_us;
interval_timer.it_interval.tv_usec = runtime_quantum_us;
int return_code = setitimer(ITIMER_REAL, &interval_timer, NULL);
if (return_code) {
perror("setitimer");
exit(1);
}
#endif
}
/**

@ -317,10 +317,11 @@ worker_thread_main(void *return_code)
/* Unmask signals */
#ifndef PREEMPT_DISABLE
software_interrupt_unmask_signal(SIGALRM);
software_interrupt_unmask_signal(SIGUSR1);
#endif
if (runtime_preemption_enabled) {
software_interrupt_unmask_signal(SIGALRM);
software_interrupt_unmask_signal(SIGUSR1);
}
signal(SIGPIPE, SIG_IGN);
/* Initialize epoll */

Loading…
Cancel
Save