diff --git a/runtime/include/sandbox.h b/runtime/include/sandbox.h index d58e212..d3d6b1a 100644 --- a/runtime/include/sandbox.h +++ b/runtime/include/sandbox.h @@ -88,7 +88,6 @@ extern void worker_thread_block_current_sandbox(void); extern void worker_thread_exit_current_sandbox(void); extern struct sandbox *worker_thread_get_next_sandbox(int interrupt); extern void worker_thread_process_io(void); -extern void worker_thread_push_sandbox_to_completion_queue(struct sandbox *sandbox); extern void __attribute__((noreturn)) worker_thread_sandbox_switch_preempt(void); extern void worker_thread_wakeup_sandbox(sandbox_t *sandbox); diff --git a/runtime/include/sandbox_completion_queue.h b/runtime/include/sandbox_completion_queue.h new file mode 100644 index 0000000..f9f8b71 --- /dev/null +++ b/runtime/include/sandbox_completion_queue.h @@ -0,0 +1,11 @@ +#ifndef SFRT_SANDBOX_COMPLETION_QUEUE_H +#define SFRT_SANDBOX_COMPLETION_QUEUE_H + +#include +#include "sandbox.h" + +void sandbox_completion_queue_add(struct sandbox *sandbox); +void sandbox_completion_queue_free(unsigned int number_to_free); +void sandbox_completion_queue_initialize(); + +#endif /* SFRT_SANDBOX_COMPLETION_QUEUE_H */ \ No newline at end of file diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c index be3ff08..5926c30 100644 --- a/runtime/src/runtime.c +++ b/runtime/src/runtime.c @@ -19,6 +19,7 @@ #include #include #include +#include #include // #include #include @@ -141,8 +142,6 @@ listener_thread_initialize(void) * Worker Thread State * **************************/ -__thread static struct ps_list_head worker_thread_completion_queue; - // context pointer to switch to when this thread gets a SIGUSR1 __thread arch_context_t *worker_thread_next_context = NULL; @@ -174,8 +173,7 @@ worker_thread_switch_to_sandbox(struct sandbox *next_sandbox) arch_context_t *current_register_context = current_sandbox == NULL ? NULL : ¤t_sandbox->ctxt; current_sandbox_set(next_sandbox); // If the current sandbox we're switching from is in a RETURNED state, add to completion queue - if (current_sandbox && current_sandbox->state == RETURNED) - worker_thread_push_sandbox_to_completion_queue(current_sandbox); + if (current_sandbox && current_sandbox->state == RETURNED) sandbox_completion_queue_add(current_sandbox); worker_thread_next_context = next_register_context; arch_context_switch(current_register_context, next_register_context); software_interrupt_enable(); @@ -329,35 +327,6 @@ worker_thread_get_next_sandbox(int in_interrupt) return sandbox; } -/** - * Adds sandbox to the completion queue - * @param sandbox - **/ -void -worker_thread_push_sandbox_to_completion_queue(struct sandbox *sandbox) -{ - assert(ps_list_singleton_d(sandbox)); - ps_list_head_append_d(&worker_thread_completion_queue, sandbox); -} - - -/** - * @brief Pops n sandboxes from the thread local completion queue and then frees them - * @param number_to_free The number of sandboxes to pop and free - * @return void - */ -static inline void -worker_thread_pop_and_free_n_sandboxes_from_completion_queue(unsigned int number_to_free) -{ - for (int i = 0; i < number_to_free; i++) { - if (ps_list_head_empty(&worker_thread_completion_queue)) break; - struct sandbox *sandbox = ps_list_head_first_d(&worker_thread_completion_queue, struct sandbox); - if (!sandbox) break; - ps_list_rem_d(sandbox); - sandbox_free(sandbox); - } -} - /** * Tries to free a completed request, executes libuv callbacks, and then gets * and returns the standbox at the head of the thread-local runqueue @@ -368,7 +337,7 @@ worker_thread_execute_runtime_maintenance_and_get_next_sandbox(void) { assert(current_sandbox_get() == NULL); // Try to free one sandbox from the completion queue - worker_thread_pop_and_free_n_sandboxes_from_completion_queue(1); + sandbox_completion_queue_free(1); // Execute libuv callbacks if (!worker_thread_is_in_callback) worker_thread_execute_libuv_event_loop(); @@ -391,7 +360,7 @@ worker_thread_main(void *return_code) arch_context_init(&worker_thread_base_context, 0, 0); sandbox_run_queue_initialize(); - ps_list_head_init(&worker_thread_completion_queue); + sandbox_completion_queue_initialize(); software_interrupt_is_disabled = 0; worker_thread_next_context = NULL; #ifndef PREEMPT_DISABLE diff --git a/runtime/src/sandbox_completion_queue.c b/runtime/src/sandbox_completion_queue.c new file mode 100644 index 0000000..5a69858 --- /dev/null +++ b/runtime/src/sandbox_completion_queue.c @@ -0,0 +1,44 @@ +#include "sandbox_completion_queue.h" + +__thread static struct ps_list_head sandbox_completion_queue; + + +void +sandbox_completion_queue_initialize() +{ + ps_list_head_init(&sandbox_completion_queue); +} + +/** + * Adds sandbox to the completion queue + * @param sandbox + **/ +void +sandbox_completion_queue_add(struct sandbox *sandbox) +{ + assert(ps_list_singleton_d(sandbox)); + ps_list_head_append_d(&sandbox_completion_queue, sandbox); +} + +static inline bool +sandbox_completion_queue_is_empty() +{ + return ps_list_head_empty(&sandbox_completion_queue); +} + +/** + * @brief Pops n sandboxes from the thread local completion queue and then frees them + * @param number_to_free The number of sandboxes to pop and free + * @return void + */ +void +sandbox_completion_queue_free(unsigned int number_to_free) +{ + for (int i = 0; i < number_to_free; i++) { + if (sandbox_completion_queue_is_empty()) break; + struct sandbox *sandbox = ps_list_head_first_d(&sandbox_completion_queue, struct sandbox); + if (!sandbox) break; + ps_list_rem_d(sandbox); + sandbox_free(sandbox); + } +} \ No newline at end of file