diff --git a/runtime/Makefile b/runtime/Makefile index de58895..e69fce6 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -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 diff --git a/runtime/experiments/bash_libraries/panic.sh b/runtime/experiments/bash_libraries/panic.sh index 8533823..a204315 100644 --- a/runtime/experiments/bash_libraries/panic.sh +++ b/runtime/experiments/bash_libraries/panic.sh @@ -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 } diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h index b0266fa..1e05489 100644 --- a/runtime/include/runtime.h +++ b/runtime/include/runtime.h @@ -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; diff --git a/runtime/include/software_interrupt.h b/runtime/include/software_interrupt.h index fca97c8..b587e90 100644 --- a/runtime/include/software_interrupt.h +++ b/runtime/include/software_interrupt.h @@ -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 * ***********/ diff --git a/runtime/src/main.c b/runtime/src/main.c index 7411dd6..6bd8866 100644 --- a/runtime/src/main.c +++ b/runtime/src/main.c @@ -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(); diff --git a/runtime/src/software_interrupt.c b/runtime/src/software_interrupt.c index c102044..5315dda 100644 --- a/runtime/src/software_interrupt.c +++ b/runtime/src/software_interrupt.c @@ -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 } /** diff --git a/runtime/src/worker_thread.c b/runtime/src/worker_thread.c index 0250401..5e6fe7a 100644 --- a/runtime/src/worker_thread.c +++ b/runtime/src/worker_thread.c @@ -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 */