Compare commits

...

3 Commits

Author SHA1 Message Date
Sean McBride e3e5c12245 Merge branch 'writeback-on-block' into sandbox-writeback-demo
3 years ago
Sean McBride 1f4097cf06 refactor: fifo_get_next
3 years ago
Sean McBride b1a5491531 feat: sandbox writeback
3 years ago

@ -55,8 +55,8 @@ arch_context_restore_fast(mcontext_t *active_context, struct arch_context *sandb
assert(active_context != NULL);
assert(sandbox_context != NULL);
/* Assumption: Base Context is only ever used by arch_context_switch */
assert(sandbox_context != &worker_thread_base_context);
/* Assumption: Not switching to the same context */
assert(active_context != &sandbox_context->mctx);
assert(sandbox_context->regs[UREG_SP]);
assert(sandbox_context->regs[UREG_IP]);

@ -2,6 +2,7 @@
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include "arch/getcycles.h"
#include "local_runqueue.h"
@ -9,6 +10,7 @@
#include "sandbox_state_history.h"
#include "sandbox_state_transition.h"
#include "sandbox_types.h"
#include "worker_thread_epoll.h"
/**
* Transitions a sandbox to the SANDBOX_RUNNABLE state.
@ -30,11 +32,9 @@ sandbox_set_as_runnable(struct sandbox *sandbox, sandbox_state_t last_state)
switch (last_state) {
case SANDBOX_INITIALIZED: {
local_runqueue_add(sandbox);
break;
}
case SANDBOX_ASLEEP: {
local_runqueue_add(sandbox);
break;
}
default: {
@ -63,4 +63,13 @@ sandbox_wakeup(struct sandbox *sandbox)
{
assert(sandbox->state == SANDBOX_ASLEEP);
sandbox_set_as_runnable(sandbox, SANDBOX_ASLEEP);
int random = rand() % 100;
if (random == 0) {
debuglog("Writeback\n");
worker_thread_epoll_remove_sandbox(sandbox);
global_request_scheduler_add(sandbox);
} else {
local_runqueue_add(sandbox);
}
}

@ -75,13 +75,23 @@ scheduler_edf_get_next()
/* Try to pull and allocate from the global queue if earlier
* This will be placed at the head of the local runqueue */
/* TODO: Only try to pull from global if we have capacity on the worker for it */
if (global_deadline < local_deadline) {
if (global_request_scheduler_remove_if_earlier(&global, local_deadline) == 0) {
assert(global != NULL);
assert(global->absolute_deadline < local_deadline);
sandbox_prepare_execution_environment(global);
assert(global->state == SANDBOX_INITIALIZED);
sandbox_set_as_runnable(global, SANDBOX_INITIALIZED);
if (global->state == SANDBOX_INITIALIZED) {
sandbox_prepare_execution_environment(global);
sandbox_set_as_runnable(global, SANDBOX_INITIALIZED);
} else {
debuglog("Resuming writeback\n");
}
assert(global->state == SANDBOX_RUNNABLE || global->state == SANDBOX_PREEMPTED);
local_runqueue_add(global);
worker_thread_epoll_add_sandbox(global);
}
}
@ -100,8 +110,16 @@ scheduler_fifo_get_next()
/* If the local runqueue is empty, pull from global request scheduler */
if (global_request_scheduler_remove(&global) < 0) goto done;
sandbox_prepare_execution_environment(global);
sandbox_set_as_runnable(global, SANDBOX_INITIALIZED);
if (global->state == SANDBOX_INITIALIZED) {
sandbox_prepare_execution_environment(global);
sandbox_set_as_runnable(global, SANDBOX_INITIALIZED);
} else {
debuglog("Resuming writeback\n");
}
assert(global->state == SANDBOX_RUNNABLE || global->state == SANDBOX_PREEMPTED);
local_runqueue_add(global);
worker_thread_epoll_add_sandbox(global);
} else if (local == current_sandbox_get()) {
/* Execute Round Robin Scheduling Logic if the head is the current sandbox */
local_runqueue_list_rotate();
@ -190,6 +208,13 @@ scheduler_log_sandbox_switch(struct sandbox *current_sandbox, struct sandbox *ne
static inline void
scheduler_preemptive_switch_to(ucontext_t *interrupted_context, struct sandbox *next)
{
// switch to base context;
if (next == NULL) {
arch_context_restore_fast(&interrupted_context->uc_mcontext, &worker_thread_base_context);
current_sandbox_set(NULL);
return;
}
/* Switch to next sandbox */
switch (next->ctxt.variant) {
case ARCH_CONTEXT_VARIANT_FAST: {
@ -235,6 +260,24 @@ scheduler_preemptive_sched(ucontext_t *interrupted_context)
/* Assumption: the current sandbox is on the runqueue, so the scheduler should always return something */
assert(next != NULL);
int random = rand() % 100;
if (random == 0) {
sandbox_preempt(interrupted_sandbox);
wasm_globals_set_i64(&interrupted_sandbox->globals, 0,
sledge_abi__current_wasm_module_instance.abi.wasmg_0, true);
arch_context_save_slow(&interrupted_sandbox->ctxt, &interrupted_context->uc_mcontext);
local_runqueue_delete(interrupted_sandbox);
/* Checking next with interrupted_sandbox off all queues */
next = scheduler_get_next();
debuglog("Writeback\n");
worker_thread_epoll_remove_sandbox(interrupted_sandbox);
global_request_scheduler_add(interrupted_sandbox);
scheduler_preemptive_switch_to(interrupted_context, next);
return;
}
/* If current equals next, no switch is necessary, so resume execution */
if (interrupted_sandbox == next) {
sandbox_interrupt_return(interrupted_sandbox, SANDBOX_RUNNING_USER);

@ -123,8 +123,6 @@ current_sandbox_init()
int rc = 0;
char *error_message = NULL;
worker_thread_epoll_add_sandbox(sandbox);
/* Initialize sandbox memory */
struct module *current_module = sandbox_get_module(sandbox);
module_initialize_memory(current_module);

@ -19,7 +19,6 @@ global_request_scheduler_minheap_add(struct sandbox *sandbox)
{
assert(sandbox);
assert(global_request_scheduler_minheap);
if (unlikely(!listener_thread_is_running())) panic("%s is only callable by the listener thread\n", __func__);
int return_code = priority_queue_enqueue(global_request_scheduler_minheap, sandbox);

Loading…
Cancel
Save