refactor: Remove preemptable

master
Sean McBride 4 years ago
parent 7e85bb4c59
commit b8364bd53e

@ -29,7 +29,6 @@ arch_context_init(struct arch_context *actx, reg_t ip, reg_t sp)
actx->regs[UREG_SP] = sp;
actx->regs[UREG_IP] = ip;
actx->preemptable = false;
}
/**

@ -10,5 +10,4 @@ struct arch_context {
arch_context_variant_t variant;
reg_t regs[UREG_COUNT];
mcontext_t mctx;
bool preemptable;
};

@ -20,8 +20,6 @@ arch_context_init(struct arch_context *actx, reg_t ip, reg_t sp)
actx->variant = ARCH_CONTEXT_VARIANT_FAST;
}
actx->preemptable = false;
if (sp) {
/*
* context_switch conventions: bp is expected to be on top of the stack

@ -96,50 +96,16 @@ sandbox_print_perf(struct sandbox *sandbox)
* becomes more intelligent, then peak linear memory size needs to be tracked
* seperately from current linear memory size.
*/
fprintf(runtime_sandbox_perf_log, "%lu,%s,%d,%s,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%u,%u\n", sandbox->id,
fprintf(runtime_sandbox_perf_log,
"%lu,%s,%d,%s,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%lu,%u,%u\n", sandbox->id,
sandbox->module->name, sandbox->module->port, sandbox_state_stringify(sandbox->state),
sandbox->module->relative_deadline, sandbox->total_time, queued_duration,
sandbox->duration_of_state.initializing, sandbox->duration_of_state.runnable,
sandbox->duration_of_state.preempted, sandbox->duration_of_state.running_kernel,
sandbox->duration_of_state.running_user, sandbox->duration_of_state.blocked,
sandbox->duration_of_state.returned, runtime_processor_speed_MHz, sandbox->memory.size);
}
static inline void
sandbox_enable_preemption(struct sandbox *sandbox)
{
#ifdef LOG_PREEMPTION
debuglog("Sandbox %lu - enabling preemption - Missed %d SIGALRM\n", sandbox->id,
software_interrupt_deferred_sigalrm);
fflush(stderr);
#endif
if (__sync_bool_compare_and_swap(&sandbox->ctxt.preemptable, 0, 1) == false) {
panic("Recursive call to current_sandbox_enable_preemption\n");
}
if (software_interrupt_deferred_sigalrm > 0) {
/* Update Max */
if (software_interrupt_deferred_sigalrm > software_interrupt_deferred_sigalrm_max[worker_thread_idx]) {
software_interrupt_deferred_sigalrm_max[worker_thread_idx] =
software_interrupt_deferred_sigalrm;
}
software_interrupt_deferred_sigalrm = 0;
// TODO: Replay. Does the replay need to be before or after enabling preemption?
}
}
static inline void
sandbox_disable_preemption(struct sandbox *sandbox)
{
#ifdef LOG_PREEMPTION
debuglog("Sandbox %lu - disabling preemption\n", sandbox->id);
fflush(stderr);
#endif
if (__sync_bool_compare_and_swap(&sandbox->ctxt.preemptable, 1, 0) == false) {
panic("Recursive call to current_sandbox_disable_preemption\n");
}
sandbox->duration_of_state[SANDBOX_UNINITIALIZED], sandbox->duration_of_state[SANDBOX_ALLOCATED],
sandbox->duration_of_state[SANDBOX_INITIALIZED], sandbox->duration_of_state[SANDBOX_RUNNABLE],
sandbox->duration_of_state[SANDBOX_PREEMPTED], sandbox->duration_of_state[SANDBOX_RUNNING_KERNEL],
sandbox->duration_of_state[SANDBOX_RUNNING_USER], sandbox->duration_of_state[SANDBOX_BLOCKED],
sandbox->duration_of_state[SANDBOX_RETURNED], sandbox->duration_of_state[SANDBOX_COMPLETE],
sandbox->duration_of_state[SANDBOX_ERROR], runtime_processor_speed_MHz, sandbox->memory.size);
}
static inline void

@ -20,16 +20,11 @@ static inline void
sandbox_set_as_blocked(struct sandbox *sandbox, sandbox_state_t last_state)
{
assert(sandbox);
uint64_t now = __getcycles();
uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change;
sandbox->state = SANDBOX_SET_AS_BLOCKED;
sandbox_state_history_append(sandbox, SANDBOX_SET_AS_BLOCKED);
sandbox->state = SANDBOX_BLOCKED;
uint64_t now = __getcycles();
switch (last_state) {
case SANDBOX_RUNNING_KERNEL: {
sandbox->duration_of_state.running_kernel += duration_of_last_state;
local_runqueue_delete(sandbox);
break;
}
@ -39,10 +34,9 @@ sandbox_set_as_blocked(struct sandbox *sandbox, sandbox_state_t last_state)
}
}
sandbox->timestamp_of.last_state_change = now;
sandbox->state = SANDBOX_BLOCKED;
/* State Change Bookkeeping */
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(sandbox, SANDBOX_BLOCKED);
runtime_sandbox_total_increment(SANDBOX_BLOCKED);
runtime_sandbox_total_decrement(last_state);

@ -22,17 +22,12 @@ static inline void
sandbox_set_as_complete(struct sandbox *sandbox, sandbox_state_t last_state)
{
assert(sandbox);
uint64_t now = __getcycles();
uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change;
sandbox->state = SANDBOX_SET_AS_COMPLETE;
sandbox_state_history_append(sandbox, SANDBOX_SET_AS_COMPLETE);
sandbox->state = SANDBOX_COMPLETE;
uint64_t now = __getcycles();
switch (last_state) {
case SANDBOX_RETURNED: {
sandbox->timestamp_of.completion = now;
sandbox->duration_of_state.returned += duration_of_last_state;
break;
}
default: {
@ -41,17 +36,17 @@ sandbox_set_as_complete(struct sandbox *sandbox, sandbox_state_t last_state)
}
}
sandbox->timestamp_of.last_state_change = now;
sandbox->state = SANDBOX_COMPLETE;
/* State Change Bookkeeping */
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(sandbox, SANDBOX_COMPLETE);
runtime_sandbox_total_increment(SANDBOX_COMPLETE);
runtime_sandbox_total_decrement(last_state);
/* Admissions Control Post Processing */
admissions_info_update(&sandbox->module->admissions_info,
sandbox->duration_of_state.running_user + sandbox->duration_of_state.running_kernel);
sandbox->duration_of_state[SANDBOX_RUNNING_USER]
+ sandbox->duration_of_state[SANDBOX_RUNNING_KERNEL]);
admissions_control_subtract(sandbox->admissions_estimate);
/* Terminal State Logging */

@ -27,20 +27,14 @@ static inline void
sandbox_set_as_error(struct sandbox *sandbox, sandbox_state_t last_state)
{
assert(sandbox);
uint64_t now = __getcycles();
uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change;
sandbox->state = SANDBOX_SET_AS_ERROR;
sandbox_state_history_append(sandbox, SANDBOX_SET_AS_ERROR);
sandbox->state = SANDBOX_ERROR;
uint64_t now = __getcycles();
switch (last_state) {
case SANDBOX_SET_AS_INITIALIZED:
case SANDBOX_UNINITIALIZED:
/* Technically, this is a degenerate sandbox that we generate by hand */
sandbox->duration_of_state.initializing += duration_of_last_state;
break;
case SANDBOX_RUNNING_KERNEL: {
sandbox->duration_of_state.running_kernel += duration_of_last_state;
local_runqueue_delete(sandbox);
break;
}
@ -50,17 +44,17 @@ sandbox_set_as_error(struct sandbox *sandbox, sandbox_state_t last_state)
}
}
uint64_t sandbox_id = sandbox->id;
sandbox->state = SANDBOX_ERROR;
/* State Change Bookkeeping */
uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change;
sandbox->duration_of_state[last_state] += duration_of_last_state;
sandbox_state_history_append(sandbox, SANDBOX_ERROR);
runtime_sandbox_total_increment(SANDBOX_ERROR);
runtime_sandbox_total_decrement(last_state);
sandbox_print_perf(sandbox);
sandbox_summarize_page_allocations(sandbox);
sandbox_free_linear_memory(sandbox);
admissions_control_subtract(sandbox->admissions_estimate);
/* Do not touch sandbox after adding to completion queue to avoid use-after-free bugs */
local_completion_queue_add(sandbox);
/* State Change Bookkeeping */
sandbox_state_history_append(sandbox, SANDBOX_ERROR);
runtime_sandbox_total_increment(SANDBOX_ERROR);
runtime_sandbox_total_decrement(last_state);
}

@ -21,18 +21,22 @@ static inline void
sandbox_set_as_initialized(struct sandbox *sandbox, struct sandbox_request *sandbox_request,
uint64_t allocation_timestamp)
{
assert(sandbox != NULL);
assert(sandbox);
assert(sandbox->state == SANDBOX_ALLOCATED);
assert(sandbox_request != NULL);
assert(allocation_timestamp > 0);
sandbox->id = sandbox_request->id;
sandbox->admissions_estimate = sandbox_request->admissions_estimate;
sandbox->state = SANDBOX_INITIALIZED;
uint64_t now = __getcycles();
/* Copy State from Sandbox Request */
sandbox->id = sandbox_request->id;
sandbox->absolute_deadline = sandbox_request->absolute_deadline;
sandbox->admissions_estimate = sandbox_request->admissions_estimate;
sandbox->client_socket_descriptor = sandbox_request->socket_descriptor;
sandbox->timestamp_of.request_arrival = sandbox_request->request_arrival_timestamp;
sandbox->timestamp_of.allocation = allocation_timestamp;
sandbox->state = SANDBOX_SET_AS_INITIALIZED;
sandbox_state_history_append(sandbox, SANDBOX_SET_AS_INITIALIZED);
/* Copy the socket descriptor and address of the client invocation */
memcpy(&sandbox->client_address, &sandbox_request->socket_address, sizeof(struct sockaddr));
/* Initialize the sandbox's context, stack, and instruction pointer */
/* stack.start points to the bottom of the usable stack, so add stack_size to get to top */
@ -42,15 +46,11 @@ sandbox_set_as_initialized(struct sandbox *sandbox, struct sandbox_request *sand
/* Initialize Parsec control structures */
ps_list_init_d(sandbox);
/* Copy the socket descriptor and address of the client invocation */
sandbox->absolute_deadline = sandbox_request->absolute_deadline;
sandbox->client_socket_descriptor = sandbox_request->socket_descriptor;
memcpy(&sandbox->client_address, &sandbox_request->socket_address, sizeof(struct sockaddr));
sandbox->timestamp_of.last_state_change = allocation_timestamp; /* We use arg to include alloc */
sandbox->state = SANDBOX_INITIALIZED;
/* State Change Bookkeeping */
sandbox->duration_of_state[SANDBOX_ALLOCATED] = now - allocation_timestamp;
sandbox->timestamp_of.allocation = allocation_timestamp;
sandbox->timestamp_of.last_state_change = allocation_timestamp;
sandbox_state_history_append(sandbox, SANDBOX_INITIALIZED);
runtime_sandbox_total_increment(SANDBOX_INITIALIZED);
}

@ -23,21 +23,11 @@ static inline void
sandbox_set_as_preempted(struct sandbox *sandbox, sandbox_state_t last_state)
{
assert(sandbox);
/* Preemption occurs indirectly via the SANDBOX_RUNNING_KERNEL state, so preemptable is set
* to false during the process of preemption.
*/
assert(sandbox->ctxt.preemptable == false);
uint64_t now = __getcycles();
uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change;
sandbox->state = SANDBOX_SET_AS_PREEMPTED;
sandbox_state_history_append(sandbox, SANDBOX_SET_AS_PREEMPTED);
sandbox->state = SANDBOX_PREEMPTED;
uint64_t now = __getcycles();
switch (last_state) {
case SANDBOX_RUNNING_KERNEL: {
sandbox->duration_of_state.preempted += duration_of_last_state;
current_sandbox_set(NULL);
break;
}
@ -47,10 +37,9 @@ sandbox_set_as_preempted(struct sandbox *sandbox, sandbox_state_t last_state)
}
}
sandbox->timestamp_of.last_state_change = now;
sandbox->state = SANDBOX_PREEMPTED;
/* State Change Bookkeeping */
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(sandbox, SANDBOX_PREEMPTED);
runtime_sandbox_total_increment(SANDBOX_PREEMPTED);
runtime_sandbox_total_decrement(last_state);

@ -23,18 +23,13 @@ static inline void
sandbox_set_as_returned(struct sandbox *sandbox, sandbox_state_t last_state)
{
assert(sandbox);
uint64_t now = __getcycles();
uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change;
sandbox->state = SANDBOX_SET_AS_RETURNED;
sandbox_state_history_append(sandbox, SANDBOX_SET_AS_RETURNED);
sandbox->state = SANDBOX_RETURNED;
uint64_t now = __getcycles();
switch (last_state) {
case SANDBOX_RUNNING_KERNEL: {
sandbox->timestamp_of.response = now;
sandbox->total_time = now - sandbox->timestamp_of.request_arrival;
sandbox->duration_of_state.running_kernel += duration_of_last_state;
local_runqueue_delete(sandbox);
sandbox_free_linear_memory(sandbox);
break;
@ -45,10 +40,9 @@ sandbox_set_as_returned(struct sandbox *sandbox, sandbox_state_t last_state)
}
}
sandbox->timestamp_of.last_state_change = now;
sandbox->state = SANDBOX_RETURNED;
/* State Change Bookkeeping */
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(sandbox, SANDBOX_RETURNED);
runtime_sandbox_total_increment(SANDBOX_RETURNED);
runtime_sandbox_total_decrement(last_state);

@ -23,21 +23,15 @@ static inline void
sandbox_set_as_runnable(struct sandbox *sandbox, sandbox_state_t last_state)
{
assert(sandbox);
uint64_t now = __getcycles();
uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change;
sandbox->state = SANDBOX_SET_AS_RUNNABLE;
sandbox_state_history_append(sandbox, SANDBOX_SET_AS_RUNNABLE);
sandbox->state = SANDBOX_RUNNABLE;
uint64_t now = __getcycles();
switch (last_state) {
case SANDBOX_INITIALIZED: {
sandbox->duration_of_state.initializing += duration_of_last_state;
local_runqueue_add(sandbox);
break;
}
case SANDBOX_BLOCKED: {
sandbox->duration_of_state.blocked += duration_of_last_state;
local_runqueue_add(sandbox);
break;
}
@ -47,10 +41,9 @@ sandbox_set_as_runnable(struct sandbox *sandbox, sandbox_state_t last_state)
}
}
sandbox->timestamp_of.last_state_change = now;
sandbox->state = SANDBOX_RUNNABLE;
/* State Change Bookkeeping */
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(sandbox, SANDBOX_RUNNABLE);
runtime_sandbox_total_increment(SANDBOX_RUNNABLE);
runtime_sandbox_total_decrement(last_state);

@ -13,31 +13,17 @@ static inline void
sandbox_set_as_running_kernel(struct sandbox *sandbox, sandbox_state_t last_state)
{
assert(sandbox);
/* Disable preemption at start of state transition */
if (last_state == SANDBOX_RUNNING_USER) {
assert(sandbox->ctxt.preemptable == true);
sandbox_disable_preemption(sandbox);
} else {
assert(sandbox->ctxt.preemptable == false);
}
uint64_t now = __getcycles();
uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change;
sandbox->state = SANDBOX_SET_AS_RUNNING_KERNEL;
sandbox_state_history_append(sandbox, SANDBOX_SET_AS_RUNNING_KERNEL);
sandbox->state = SANDBOX_RUNNING_KERNEL;
uint64_t now = __getcycles();
switch (last_state) {
case SANDBOX_RUNNING_USER: {
assert(sandbox == current_sandbox_get());
sandbox->duration_of_state.running_user += duration_of_last_state;
assert(runtime_worker_threads_deadline[worker_thread_idx] == sandbox->absolute_deadline);
break;
}
case SANDBOX_RUNNABLE: {
assert(sandbox);
sandbox->duration_of_state.runnable += duration_of_last_state;
current_sandbox_set(sandbox);
/* Does not handle context switch because the caller knows if we need to use fast or slow switched. We
* can fix this by breakout out SANDBOX_RUNNABLE and SANDBOX_PREEMPTED */
@ -46,7 +32,6 @@ sandbox_set_as_running_kernel(struct sandbox *sandbox, sandbox_state_t last_stat
case SANDBOX_PREEMPTED: {
assert(sandbox);
assert(sandbox->interrupted_state == SANDBOX_RUNNING_USER);
sandbox->duration_of_state.preempted += duration_of_last_state;
current_sandbox_set(sandbox);
/* Does not handle context switch because the caller knows if we need to use fast or slow switched. We
* can fix this by breakout out SANDBOX_RUNNABLE and SANDBOX_PREEMPTED */
@ -58,10 +43,9 @@ sandbox_set_as_running_kernel(struct sandbox *sandbox, sandbox_state_t last_stat
}
}
sandbox->timestamp_of.last_state_change = now;
sandbox->state = SANDBOX_RUNNING_KERNEL;
/* State Change Bookkeeping */
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(sandbox, SANDBOX_RUNNING_KERNEL);
runtime_sandbox_total_increment(SANDBOX_RUNNING_KERNEL);
runtime_sandbox_total_decrement(last_state);

@ -14,14 +14,10 @@ sandbox_set_as_running_user(struct sandbox *sandbox, sandbox_state_t last_state)
{
assert(sandbox);
uint64_t now = __getcycles();
uint64_t duration_of_last_state = now - sandbox->timestamp_of.last_state_change;
sandbox->state = SANDBOX_SET_AS_RUNNING_USER;
uint64_t now = __getcycles();
switch (last_state) {
case SANDBOX_RUNNING_KERNEL: {
sandbox->duration_of_state.running_user += duration_of_last_state;
assert(sandbox == current_sandbox_get());
assert(runtime_worker_threads_deadline[worker_thread_idx] == sandbox->absolute_deadline);
@ -33,16 +29,15 @@ sandbox_set_as_running_user(struct sandbox *sandbox, sandbox_state_t last_state)
}
}
sandbox->timestamp_of.last_state_change = now;
sandbox->state = SANDBOX_RUNNING_USER;
/* State Change Bookkeeping */
sandbox->duration_of_state[last_state] += (now - sandbox->timestamp_of.last_state_change);
sandbox->timestamp_of.last_state_change = now;
sandbox_state_history_append(sandbox, SANDBOX_RUNNING_USER);
runtime_sandbox_total_increment(SANDBOX_RUNNING_USER);
runtime_sandbox_total_decrement(last_state);
/* Enable preemption at the end of state transition*/
assert(last_state == SANDBOX_RUNNING_KERNEL);
sandbox_enable_preemption(sandbox);
/* WARNING: This state change needs to be at the end of this transition because all code below this assignment
* is preemptable */
sandbox->state = SANDBOX_RUNNING_USER;
}

@ -10,40 +10,18 @@ typedef enum
{
SANDBOX_UNINITIALIZED = 0, /* Assumption: mmap zeros out structure */
SANDBOX_ALLOCATED,
SANDBOX_SET_AS_INITIALIZED,
SANDBOX_INITIALIZED,
SANDBOX_SET_AS_RUNNABLE,
SANDBOX_RUNNABLE,
SANDBOX_SET_AS_PREEMPTED,
SANDBOX_PREEMPTED,
SANDBOX_SET_AS_RUNNING_KERNEL,
SANDBOX_RUNNING_KERNEL,
SANDBOX_SET_AS_RUNNING_USER,
SANDBOX_RUNNING_USER,
SANDBOX_SET_AS_BLOCKED,
SANDBOX_BLOCKED,
SANDBOX_SET_AS_RETURNED,
SANDBOX_RETURNED,
SANDBOX_SET_AS_COMPLETE,
SANDBOX_COMPLETE,
SANDBOX_SET_AS_ERROR,
SANDBOX_ERROR,
SANDBOX_STATE_COUNT
} sandbox_state_t;
/* Duration of time (in cycles) that the sandbox is in each state */
struct sandbox_state_durations {
uint64_t initializing;
uint64_t runnable;
uint64_t running_kernel;
uint64_t running_user;
uint64_t preempted;
uint64_t blocked;
uint64_t returned;
};
extern const bool sandbox_state_is_terminal[SANDBOX_STATE_COUNT];
extern const char *sandbox_state_labels[SANDBOX_STATE_COUNT];
static inline const char *
@ -69,7 +47,6 @@ static inline void
runtime_sandbox_total_increment(sandbox_state_t state)
{
#ifdef LOG_SANDBOX_COUNT
if (!sandbox_state_is_terminal[state]) panic("Unexpectedly logging intermediate transition state");
atomic_fetch_add(&sandbox_state_count[state], 1);
#endif
}

@ -101,8 +101,8 @@ struct sandbox {
struct wasm_memory memory;
/* Scheduling and Temporal State */
struct sandbox_timestamps timestamp_of;
struct sandbox_state_durations duration_of_state;
struct sandbox_timestamps timestamp_of;
uint64_t duration_of_state[SANDBOX_STATE_COUNT];
uint64_t absolute_deadline;
uint64_t admissions_estimate; /* estimated execution time (cycles) * runtime_admissions_granularity / relative

@ -60,11 +60,8 @@ worker_thread_execute_epoll_loop(void)
}
switch (sandbox->state) {
case SANDBOX_SET_AS_RETURNED:
case SANDBOX_RETURNED:
case SANDBOX_SET_AS_COMPLETE:
case SANDBOX_COMPLETE:
case SANDBOX_SET_AS_ERROR:
case SANDBOX_ERROR:
panic("Expected to have closed socket");
default:

@ -59,9 +59,7 @@ current_sandbox_start(void)
/* Executing the function */
int32_t argument_count = 0;
assert(sandbox->state == SANDBOX_RUNNING_KERNEL);
assert(sandbox->ctxt.preemptable == false);
sandbox_set_as_running_user(sandbox, SANDBOX_RUNNING_KERNEL);
assert(sandbox->ctxt.preemptable == true);
sandbox->return_value = module_entrypoint(current_module, argument_count, sandbox->arguments_offset);
assert(sandbox->state == SANDBOX_RUNNING_USER);
sandbox_set_as_running_kernel(sandbox, SANDBOX_RUNNING_USER);

@ -73,6 +73,8 @@ sandbox_allocate_memory(struct module *module)
sandbox->memory.size = memory_size;
sandbox->memory.max = memory_max;
for (int i = 0; i < SANDBOX_STATE_COUNT; i++) { sandbox->duration_of_state[i] = 0; }
done:
return sandbox;
set_rw_failed:
@ -171,14 +173,14 @@ err_stack_allocation_failed:
* This is a degenerate sandbox that never successfully completed initialization, so we need to
* hand jam some things to be able to cleanly transition to ERROR state
*/
sandbox->state = SANDBOX_SET_AS_INITIALIZED;
sandbox->state = SANDBOX_UNINITIALIZED;
sandbox->timestamp_of.last_state_change = now;
#ifdef LOG_SANDBOX_MEMORY_PROFILE
sandbox->timestamp_of.page_allocations_size = 0;
#endif
ps_list_init_d(sandbox);
err_memory_allocation_failed:
sandbox_set_as_error(sandbox, SANDBOX_SET_AS_INITIALIZED);
sandbox_set_as_error(sandbox, SANDBOX_UNINITIALIZED);
perror(error_message);
sandbox = NULL;
goto done;

@ -7,41 +7,19 @@
#include "debuglog.h"
#include "sandbox_state.h"
const bool sandbox_state_is_terminal[SANDBOX_STATE_COUNT] = {
[SANDBOX_UNINITIALIZED] = false, [SANDBOX_ALLOCATED] = false,
[SANDBOX_INITIALIZED] = true, [SANDBOX_SET_AS_RUNNABLE] = false,
[SANDBOX_RUNNABLE] = true, [SANDBOX_SET_AS_PREEMPTED] = false,
[SANDBOX_PREEMPTED] = true, [SANDBOX_SET_AS_RUNNING_KERNEL] = false,
[SANDBOX_RUNNING_KERNEL] = true, [SANDBOX_SET_AS_RUNNING_USER] = false,
[SANDBOX_RUNNING_USER] = true, [SANDBOX_SET_AS_BLOCKED] = false,
[SANDBOX_BLOCKED] = true, [SANDBOX_SET_AS_RETURNED] = false,
[SANDBOX_RETURNED] = true, [SANDBOX_SET_AS_COMPLETE] = false,
[SANDBOX_COMPLETE] = true, [SANDBOX_SET_AS_ERROR] = false,
[SANDBOX_ERROR] = true
};
const char *sandbox_state_labels[SANDBOX_STATE_COUNT] = {
[SANDBOX_UNINITIALIZED] = "Uninitialized",
[SANDBOX_ALLOCATED] = "Allocated",
[SANDBOX_SET_AS_INITIALIZED] = "Transitioning to Initialized",
[SANDBOX_INITIALIZED] = "Initialized",
[SANDBOX_SET_AS_RUNNABLE] = "Transitioning to Runnable",
[SANDBOX_RUNNABLE] = "Runnable",
[SANDBOX_SET_AS_PREEMPTED] = "Transitioning to Preempted",
[SANDBOX_PREEMPTED] = "Preempted",
[SANDBOX_SET_AS_RUNNING_KERNEL] = "Transitioning to Running Kernel",
[SANDBOX_RUNNING_KERNEL] = "Running Kernel",
[SANDBOX_SET_AS_RUNNING_USER] = "Transitioning to Running User",
[SANDBOX_RUNNING_USER] = "Running User",
[SANDBOX_SET_AS_BLOCKED] = "Transitioning to Blocked",
[SANDBOX_BLOCKED] = "Blocked",
[SANDBOX_SET_AS_RETURNED] = "Transitioning to Returned",
[SANDBOX_RETURNED] = "Returned",
[SANDBOX_SET_AS_COMPLETE] = "Transitioning to Complete",
[SANDBOX_COMPLETE] = "Complete",
[SANDBOX_SET_AS_ERROR] = "Transitioning to Error",
[SANDBOX_ERROR] = "Error"
[SANDBOX_UNINITIALIZED] = "Uninitialized",
[SANDBOX_ALLOCATED] = "Allocated",
[SANDBOX_INITIALIZED] = "Initialized",
[SANDBOX_RUNNABLE] = "Runnable",
[SANDBOX_PREEMPTED] = "Preempted",
[SANDBOX_RUNNING_KERNEL] = "Running Kernel",
[SANDBOX_RUNNING_USER] = "Running User",
[SANDBOX_BLOCKED] = "Blocked",
[SANDBOX_RETURNED] = "Returned",
[SANDBOX_COMPLETE] = "Complete",
[SANDBOX_ERROR] = "Error"
};
#ifdef LOG_SANDBOX_COUNT

@ -139,7 +139,6 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void
assert(runtime_preemption_enabled);
/* Signals should not nest */
/* TODO: Better atomic instruction here to check and set? */
assert(software_interrupt_signal_depth == 0);
atomic_fetch_add(&software_interrupt_signal_depth, 1);
@ -148,18 +147,17 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void
switch (signal_type) {
case SIGALRM: {
bool preemptable = false;
if (current_sandbox) {
preemptable = current_sandbox->ctxt.preemptable;
current_sandbox->interrupted_state = current_sandbox->state;
if (preemptable && current_sandbox->state == SANDBOX_RUNNING_USER) {
sandbox_set_as_running_kernel(current_sandbox, SANDBOX_RUNNING_USER);
}
}
sigalrm_propagate_workers(signal_info);
if (preemptable) {
/* Current Sandbox is NULL when the base worker context is active. This already executes scheduling
* logic, so just return. */
if (!current_sandbox) goto done;
/* We need to track what state was interrupted to conditionally restore user running after preemption */
current_sandbox->interrupted_state = current_sandbox->state;
if (current_sandbox->state == SANDBOX_RUNNING_USER) {
sandbox_set_as_running_kernel(current_sandbox, SANDBOX_RUNNING_USER);
atomic_store(&software_interrupt_deferred_sigalrm, 0);
current_sandbox = scheduler_preempt(interrupted_context);
} else {

Loading…
Cancel
Save