#include "current_sandbox.h" #include "local_runqueue.h" #include "worker_thread.h" /* current sandbox that is active.. */ static __thread struct sandbox *worker_thread_current_sandbox = NULL; __thread struct sandbox_context_cache local_sandbox_context_cache = { .linear_memory_start = NULL, .linear_memory_size = 0, .module_indirect_table = NULL, }; /** * Getter for the current sandbox executing on this thread * @returns the current sandbox executing on this thread */ struct sandbox * current_sandbox_get(void) { return worker_thread_current_sandbox; } /** * Setter for the current sandbox executing on this thread * @param sandbox the sandbox we are setting this thread to run */ void current_sandbox_set(struct sandbox *sandbox) { /* Unpack hierarchy to avoid pointer chasing */ if (sandbox == NULL) { local_sandbox_context_cache = (struct sandbox_context_cache){ .linear_memory_start = NULL, .linear_memory_size = 0, .module_indirect_table = NULL, }; worker_thread_current_sandbox = NULL; } else { local_sandbox_context_cache = (struct sandbox_context_cache){ .linear_memory_start = sandbox->linear_memory_start, .linear_memory_size = sandbox->linear_memory_size, .module_indirect_table = sandbox->module->indirect_table, }; worker_thread_current_sandbox = sandbox; } } /** * Mark the currently executing sandbox as blocked, remove it from the local runqueue, * and switch to base context */ void current_sandbox_block(void) { software_interrupt_disable(); /* Remove the sandbox we were just executing from the runqueue and mark as blocked */ struct sandbox *current_sandbox = current_sandbox_get(); assert(current_sandbox->state == SANDBOX_RUNNING); sandbox_set_as_blocked(current_sandbox, SANDBOX_RUNNING); generic_thread_dump_lock_overhead(); /* The worker thread seems to "spin" on a blocked sandbox, so try to execute another sandbox for one quantum * after blocking to give time for the action to resolve */ struct sandbox *next_sandbox = local_runqueue_get_next(); if (next_sandbox != NULL) { sandbox_switch_to(next_sandbox); } else { worker_thread_switch_to_base_context(); }; }