diff --git a/runtime/include/arch/x86_64/context.h b/runtime/include/arch/x86_64/context.h index 9cd7a04..3204f04 100644 --- a/runtime/include/arch/x86_64/context.h +++ b/runtime/include/arch/x86_64/context.h @@ -120,6 +120,9 @@ arch_mcontext_save(struct arch_context *ctx, mcontext_t *mc) static inline int arch_context_switch(struct arch_context *current, struct arch_context *next) { + /* Assumption: Software Interrupts are disabled by caller */ + assert(software_interrupt_is_disabled); + /* if both current and next are NULL, there is no state change */ assert(current != NULL || next != NULL); diff --git a/runtime/include/module.h b/runtime/include/module.h index 4544de1..27774e5 100644 --- a/runtime/include/module.h +++ b/runtime/include/module.h @@ -2,6 +2,8 @@ #include +#include "panic.h" +#include "software_interrupt.h" #include "types.h" struct module { @@ -127,24 +129,21 @@ module_initialize_memory(struct module *module) /** * Validate module, defined as having a non-NULL dynamical library handle and entry function pointer * @param module - module to validate - * @return true if valid. false if invalid */ -static inline bool -module_is_valid(struct module *module) +static inline void +module_validate(struct module *module) { + /* Assumption: Software Interrupts are disabled by caller */ + assert(!software_interrupt_is_enabled()); + if (!module) { - fprintf(stderr, "%lu | module %p | module is unexpectedly NULL\n", pthread_self(), module); - return false; + panic("%lu | module %p | module is unexpectedly NULL\n", pthread_self(), module); } else if (!module->dynamic_library_handle) { - fprintf(stderr, "%lu | module %p | module->dynamic_library_handle is unexpectedly NULL\n", - pthread_self(), module); - return false; + panic("%lu | module %p | module->dynamic_library_handle is unexpectedly NULL\n", pthread_self(), + module); } else if (!module->main) { - fprintf(stderr, "%lu | module %p | module->main is unexpectedly NULL\n", pthread_self(), module); - return false; + panic("%lu | module %p | module->main is unexpectedly NULL\n", pthread_self(), module); } - - return true; } /** diff --git a/runtime/include/software_interrupt.h b/runtime/include/software_interrupt.h index bb167b5..959025e 100644 --- a/runtime/include/software_interrupt.h +++ b/runtime/include/software_interrupt.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -31,7 +32,8 @@ software_interrupt_disable(void) static inline void software_interrupt_enable(void) { - if (__sync_bool_compare_and_swap(&software_interrupt_is_disabled, 1, 0) == false) assert(0); + if (__sync_bool_compare_and_swap(&software_interrupt_is_disabled, 1, 0) == false) + panic("Recursive call to software_interrupt_enable\n"); } /** diff --git a/runtime/src/global_request_scheduler.c b/runtime/src/global_request_scheduler.c index 270e8fd..b83fea4 100644 --- a/runtime/src/global_request_scheduler.c +++ b/runtime/src/global_request_scheduler.c @@ -33,6 +33,7 @@ static struct global_request_scheduler_config global_request_scheduler = { .add_ void global_request_scheduler_initialize(struct global_request_scheduler_config *config) { + assert(config != NULL); memcpy(&global_request_scheduler, config, sizeof(struct global_request_scheduler_config)); } @@ -44,6 +45,7 @@ global_request_scheduler_initialize(struct global_request_scheduler_config *conf struct sandbox_request * global_request_scheduler_add(struct sandbox_request *sandbox_request) { + assert(sandbox_request != NULL); return global_request_scheduler.add_fn(sandbox_request); } @@ -55,6 +57,7 @@ global_request_scheduler_add(struct sandbox_request *sandbox_request) int global_request_scheduler_remove(struct sandbox_request **removed_sandbox) { + assert(removed_sandbox != NULL); return global_request_scheduler.remove_fn(removed_sandbox); } diff --git a/runtime/src/local_runqueue_list.c b/runtime/src/local_runqueue_list.c index da2cd89..6249804 100644 --- a/runtime/src/local_runqueue_list.c +++ b/runtime/src/local_runqueue_list.c @@ -57,6 +57,9 @@ local_runqueue_list_get_next() done: return sandbox; sandbox_allocate_err: + fprintf(stderr, + "local_runqueue_list_get_next failed to allocate sandbox, returning request to global request " + "scheduler\n"); global_request_scheduler_add(sandbox_request); err: sandbox = NULL; diff --git a/runtime/src/local_runqueue_minheap.c b/runtime/src/local_runqueue_minheap.c index db3277f..15cbcbb 100644 --- a/runtime/src/local_runqueue_minheap.c +++ b/runtime/src/local_runqueue_minheap.c @@ -6,6 +6,7 @@ #include "local_runqueue_minheap.h" #include "panic.h" #include "priority_queue.h" +#include "software_interrupt.h" __thread static struct priority_queue local_runqueue_minheap; @@ -70,6 +71,9 @@ local_runqueue_minheap_delete(struct sandbox *sandbox) struct sandbox * local_runqueue_minheap_get_next() { + /* Assumption: Software Interrupts are disabed by caller */ + assert(!software_interrupt_is_enabled()); + struct sandbox * sandbox = NULL; struct sandbox_request *sandbox_request; int sandbox_rc = local_runqueue_minheap_remove(&sandbox); @@ -97,6 +101,8 @@ local_runqueue_minheap_get_next() done: return sandbox; sandbox_allocate_err: + fprintf(stderr, "local_runqueue_minheap_get_next failed to allocating sandbox. Readding request to global " + "request scheduler\n"); global_request_scheduler_add(sandbox_request); err: sandbox = NULL; @@ -112,9 +118,8 @@ err: void local_runqueue_minheap_preempt(ucontext_t *user_context) { - assert(user_context != NULL); - - software_interrupt_disable(); /* no nesting! */ + /* Assumption: Software Interrupts are disabed by caller */ + assert(!software_interrupt_is_enabled()); struct sandbox *current_sandbox = current_sandbox_get(); @@ -147,13 +152,11 @@ local_runqueue_minheap_preempt(ucontext_t *user_context) /* Allocate the request */ struct sandbox *next_sandbox; /* If sandbox allocation fails, add the request back and exit*/ - assert(software_interrupt_is_disabled); if (sandbox_allocate(&next_sandbox, sandbox_request) == -1) goto err_sandbox_allocate; /* Set as runnable and add it to the runqueue */ next_sandbox->state = SANDBOX_RUNNABLE; local_runqueue_add(next_sandbox); - assert(software_interrupt_is_disabled); /* Save the context of the currently executing sandbox before switching from it */ arch_mcontext_save(¤t_sandbox->ctxt, &user_context->uc_mcontext); @@ -173,7 +176,10 @@ done: if (should_enable_software_interrupt) software_interrupt_enable(); return; err_sandbox_allocate: - assert(sandbox_request != NULL); + assert(sandbox_request); + fprintf(stderr, + "local_runqueue_minheap_preempt failed to allocate sandbox, returning request to global request " + "scheduler\n"); global_request_scheduler_add(sandbox_request); err: goto done; diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index 4dffbea..06bc4bc 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -389,10 +389,13 @@ err_stack_allocation_failed: int sandbox_allocate(struct sandbox **sandbox, struct sandbox_request *sandbox_request) { + /* Assumption: Caller has disabled software interrupts */ + assert(!software_interrupt_is_enabled()); + + /* Validate Arguments */ assert(sandbox != NULL); assert(sandbox_request != NULL); - assert(sandbox_request->module != NULL); - assert(module_is_valid(sandbox_request->module)); + module_validate(sandbox_request->module); char *error_message = ""; int rc; diff --git a/runtime/src/software_interrupt.c b/runtime/src/software_interrupt.c index fc4c249..01baabf 100644 --- a/runtime/src/software_interrupt.c +++ b/runtime/src/software_interrupt.c @@ -111,6 +111,7 @@ software_interrupt_handle_signals(int signal_type, siginfo_t *signal_info, void if (current_sandbox->state == SANDBOX_RETURNED) return; /* Preempt */ + software_interrupt_disable(); local_runqueue_preempt(user_context); return;