diff --git a/runtime/include/sandbox.h b/runtime/include/sandbox.h index 79040ea..4d4438f 100644 --- a/runtime/include/sandbox.h +++ b/runtime/include/sandbox.h @@ -283,4 +283,5 @@ void sandbox_set_as_runnable(struct sandbox *sandbox); void sandbox_set_as_running(struct sandbox *sandbox); void sandbox_set_as_blocked(struct sandbox *sandbox); void sandbox_set_as_preempted(struct sandbox *sandbox); +void sandbox_set_as_returned(struct sandbox *sandbox); void sandbox_set_as_complete(struct sandbox *sandbox); diff --git a/runtime/src/local_runqueue_minheap.c b/runtime/src/local_runqueue_minheap.c index 3e18da3..655733b 100644 --- a/runtime/src/local_runqueue_minheap.c +++ b/runtime/src/local_runqueue_minheap.c @@ -102,7 +102,7 @@ local_runqueue_minheap_get_next() done: return sandbox; sandbox_allocate_err: - debuglog("local_runqueue_minheap_get_next failed to allocating sandbox. Readding request to global " + debuglog("local_runqueue_minheap_get_next failed to allocate sandbox. Adding request back to global " "request scheduler\n"); global_request_scheduler_add(sandbox_request); err: diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index e0b9ee8..7b54abd 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -373,6 +373,10 @@ current_sandbox_main(void) sandbox->response_timestamp = __getcycles(); + software_interrupt_disable(); + sandbox_set_as_returned(sandbox); + software_interrupt_enable(); + done: /* Cleanup connection and exit sandbox */ sandbox_close_http(sandbox); @@ -686,6 +690,43 @@ sandbox_set_as_blocked(struct sandbox *sandbox) sandbox->state = SANDBOX_BLOCKED; } +/** + * Transitions a sandbox to the SANDBOX_RETURNED state. + * This occurs when a sandbox is executing and runs to completion. + * Automatically removes the sandbox from the runqueue and unmaps linear memory. + * Because the stack is still in use, freeing the stack is deferred until later + * @param sandbox the blocking sandbox + */ +void +sandbox_set_as_returned(struct sandbox *sandbox) +{ + assert(sandbox); + uint64_t now = __getcycles(); + uint64_t duration_of_last_state = now - sandbox->last_state_change_timestamp; + sandbox_state_t last_state = sandbox->state; + sandbox->state = SANDBOX_SET_AS_RETURNED; + debuglog("Thread %lu | Sandbox %lu | %s => Returned\n", pthread_self(), sandbox->allocation_timestamp, + sandbox_state_stringify(last_state)); + + switch (last_state) { + case SANDBOX_RUNNING: { + sandbox->response_timestamp = now; + sandbox->total_time = now - sandbox->request_arrival_timestamp; + sandbox->running_duration += duration_of_last_state; + local_runqueue_delete(sandbox); + sandbox_free_linear_memory(sandbox); + break; + } + default: { + panic("Thread %lu | Sandbox %lu | Illegal transition from %s to Returned\n", pthread_self(), + sandbox->allocation_timestamp, sandbox_state_stringify(last_state)); + } + } + + sandbox->last_state_change_timestamp = now; + sandbox->state = SANDBOX_RETURNED; +} + /** * Transitions a sandbox from the SANDBOX_RETURNED state to the SANDBOX_COMPLETE state. * Adds the sandbox to the completion queue @@ -792,7 +833,7 @@ sandbox_free(struct sandbox *sandbox) { assert(sandbox != NULL); assert(sandbox != current_sandbox_get()); - assert(sandbox->state == SANDBOX_UNINITIALIZED || sandbox->state == SANDBOX_RETURNED); + assert(sandbox->state == SANDBOX_ERROR || sandbox->state == SANDBOX_COMPLETE); char *error_message = NULL; int rc; diff --git a/runtime/src/worker_thread.c b/runtime/src/worker_thread.c index ce14ae3..7d08e67 100644 --- a/runtime/src/worker_thread.c +++ b/runtime/src/worker_thread.c @@ -117,6 +117,7 @@ worker_thread_switch_to_base_context() assert(!software_interrupt_is_enabled()); struct sandbox *current_sandbox = current_sandbox_get(); + worker_thread_transition_exiting_sandbox(current_sandbox); /* Assumption: Base Context should never switch to Base Context */ assert(current_sandbox != NULL); @@ -282,22 +283,7 @@ __attribute__((noreturn)) void worker_thread_on_sandbox_exit(struct sandbox *exiting_sandbox) { assert(exiting_sandbox); - debuglog("Exiting %lu\n", exiting_sandbox->request_arrival_timestamp); - - /* Because the stack is still in use, only unmap linear memory and defer free resources until "main - function execution" */ - sandbox_free_linear_memory(exiting_sandbox); - - /* TODO: I do not understand when software interrupts must be disabled? */ software_interrupt_disable(); - local_runqueue_delete(exiting_sandbox); - exiting_sandbox->state = SANDBOX_RETURNED; - - sandbox_print_perf(exiting_sandbox); - local_completion_queue_add(exiting_sandbox); - - /* This should force return to main event loop */ worker_thread_switch_to_base_context(); - assert(0); }