From 61c7ccea0c63affd9d244b2215bf34962670dd7f Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Mon, 27 Apr 2020 16:03:30 -0400 Subject: [PATCH] feat: implement PQ-based runqueue --- runtime/include/sandbox_run_queue.h | 27 ++++++----- runtime/include/sandbox_run_queue_fifo.h | 8 ++++ runtime/include/sandbox_run_queue_ps.h | 8 ++++ runtime/src/runtime.c | 16 ++++--- runtime/src/sandbox_run_queue.c | 47 ++++++++----------- runtime/src/sandbox_run_queue_fifo.c | 60 ++++++++++++++++++++++++ runtime/src/sandbox_run_queue_ps.c | 56 ++++++++++++++++++++++ 7 files changed, 175 insertions(+), 47 deletions(-) create mode 100644 runtime/include/sandbox_run_queue_fifo.h create mode 100644 runtime/include/sandbox_run_queue_ps.h create mode 100644 runtime/src/sandbox_run_queue_fifo.c create mode 100644 runtime/src/sandbox_run_queue_ps.c diff --git a/runtime/include/sandbox_run_queue.h b/runtime/include/sandbox_run_queue.h index b4b42cd..486b298 100644 --- a/runtime/include/sandbox_run_queue.h +++ b/runtime/include/sandbox_run_queue.h @@ -2,23 +2,24 @@ #define SFRT_SANDBOX_RUN_QUEUE_H #include +#include -#include "sandbox.h" +// Returns pointer back if successful, null otherwise +typedef struct sandbox *(*sandbox_run_queue_add_t)(struct sandbox *); +typedef struct sandbox *(*sandbox_run_queue_remove_t)(void); +typedef bool (*sandbox_run_queue_is_empty_t)(void); -void sandbox_run_queue_initialize(); +typedef struct sandbox_run_queue_config_t { + sandbox_run_queue_add_t add; + sandbox_run_queue_is_empty_t is_empty; + sandbox_run_queue_remove_t remove; +} sandbox_run_queue_config_t; -bool sandbox_run_queue_is_empty(); -// Get the sandbox at the head of the thread local runqueue -struct sandbox *sandbox_run_queue_get_head(); +void sandbox_run_queue_initialize(sandbox_run_queue_config_t *config); -// Remove a sandbox from the runqueue -void sandbox_run_queue_remove(struct sandbox *sandbox_to_remove); - -/** - * Append the sandbox to the worker_thread_run_queue - * @param sandbox_to_append - */ -void sandbox_run_queue_append(struct sandbox *sandbox_to_append); +struct sandbox *sandbox_run_queue_add(struct sandbox *); +struct sandbox *sandbox_run_queue_remove(); +bool sandbox_run_queue_is_empty(); #endif /* SFRT_SANDBOX_RUN_QUEUE_H */ \ No newline at end of file diff --git a/runtime/include/sandbox_run_queue_fifo.h b/runtime/include/sandbox_run_queue_fifo.h new file mode 100644 index 0000000..e1093ed --- /dev/null +++ b/runtime/include/sandbox_run_queue_fifo.h @@ -0,0 +1,8 @@ +#ifndef SFRT_SANDBOX_RUN_QUEUE_FIFO_H +#define SFRT_SANDBOX_RUN_QUEUE_FIFO_H + +#include "sandbox.h" + +void sandbox_run_queue_fifo_initialize(); + +#endif /* SFRT_SANDBOX_RUN_QUEUE_FIFO_H */ \ No newline at end of file diff --git a/runtime/include/sandbox_run_queue_ps.h b/runtime/include/sandbox_run_queue_ps.h new file mode 100644 index 0000000..196cb74 --- /dev/null +++ b/runtime/include/sandbox_run_queue_ps.h @@ -0,0 +1,8 @@ +#ifndef SFRT_SANDBOX_RUN_QUEUE_FIFO_H +#define SFRT_SANDBOX_RUN_QUEUE_FIFO_H + +#include "sandbox.h" + +void sandbox_run_queue_ps_initialize(); + +#endif /* SFRT_SANDBOX_RUN_QUEUE_FIFO_H */ \ No newline at end of file diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c index 375fea2..2432430 100644 --- a/runtime/src/runtime.c +++ b/runtime/src/runtime.c @@ -24,6 +24,8 @@ // #include #include #include +// #include +#include #include #include @@ -205,7 +207,7 @@ worker_thread_wakeup_sandbox(sandbox_t *sandbox) // debuglog("[%p: %s]\n", sandbox, sandbox->module->name); if (sandbox->state == BLOCKED) { sandbox->state = RUNNABLE; - sandbox_run_queue_append(sandbox); + sandbox_run_queue_add(sandbox); } software_interrupt_enable(); } @@ -287,7 +289,7 @@ worker_thread_pull_and_process_sandbox_requests(void) free(sandbox_request); // Set the sandbox as runnable and place on the local runqueue sandbox->state = RUNNABLE; - sandbox_run_queue_append(sandbox); + sandbox_run_queue_add(sandbox); total_sandboxes_pulled++; } @@ -323,10 +325,9 @@ worker_thread_get_next_sandbox() } // Execute Round Robin Scheduling Logic - struct sandbox *next_sandbox = sandbox_run_queue_get_head(); + struct sandbox *next_sandbox = sandbox_run_queue_remove(); assert(next_sandbox->state != RETURNED); - sandbox_run_queue_remove(next_sandbox); - sandbox_run_queue_append(next_sandbox); + sandbox_run_queue_add(next_sandbox); debuglog("[%p: %s]\n", next_sandbox, next_sandbox->module->name); return next_sandbox; @@ -342,7 +343,10 @@ worker_thread_main(void *return_code) { // Initialize Worker State arch_context_init(&worker_thread_base_context, 0, 0); - sandbox_run_queue_initialize(); + + // sandbox_run_queue_fifo_initialize(); + sandbox_run_queue_ps_initialize(); + sandbox_completion_queue_initialize(); software_interrupt_is_disabled = false; worker_thread_next_context = NULL; diff --git a/runtime/src/sandbox_run_queue.c b/runtime/src/sandbox_run_queue.c index 9dd76bc..48bfd07 100644 --- a/runtime/src/sandbox_run_queue.c +++ b/runtime/src/sandbox_run_queue.c @@ -1,42 +1,33 @@ -#include "sandbox_run_queue.h" +#include -__thread static struct ps_list_head sandbox_run_queue; -void -sandbox_run_queue_initialize() -{ - ps_list_head_init(&sandbox_run_queue); -} +// The global of our polymorphic interface +static sandbox_run_queue_config_t sandbox_run_queue; -bool -sandbox_run_queue_is_empty() +// Initializes a concrete implementation of the sandbox request scheduler interface +void +sandbox_run_queue_initialize(sandbox_run_queue_config_t *config) { - return ps_list_head_empty(&sandbox_run_queue); + memcpy(&sandbox_run_queue, config, sizeof(sandbox_run_queue_config_t)); } - -// Get the sandbox at the head of the thread local runqueue +// Adds a sandbox request struct sandbox * -sandbox_run_queue_get_head() +sandbox_run_queue_add(struct sandbox *sandbox) { - return ps_list_head_first_d(&sandbox_run_queue, struct sandbox); + assert(sandbox_run_queue.add != NULL); + return sandbox_run_queue.add(sandbox); } -/** - * Removes the thread from the thread-local runqueue - * @param sandbox sandbox - **/ -void -sandbox_run_queue_remove(struct sandbox *sandbox_to_remove) +// Removes a sandbox request +struct sandbox * +sandbox_run_queue_remove() { - ps_list_rem_d(sandbox_to_remove); + assert(sandbox_run_queue.remove != NULL); + return sandbox_run_queue.remove(); } -// Append a sandbox to the runqueue -void -sandbox_run_queue_append(struct sandbox *sandbox_to_append) +bool +sandbox_run_queue_is_empty() { - assert(ps_list_singleton_d(sandbox_to_append)); - // fprintf(stderr, "(%d,%lu) %s: run %p, %s\n", sched_getcpu(), pthread_self(), __func__, s, - // s->module->name); - ps_list_head_append_d(&sandbox_run_queue, sandbox_to_append); + return sandbox_run_queue_is_empty(); } \ No newline at end of file diff --git a/runtime/src/sandbox_run_queue_fifo.c b/runtime/src/sandbox_run_queue_fifo.c new file mode 100644 index 0000000..223c13e --- /dev/null +++ b/runtime/src/sandbox_run_queue_fifo.c @@ -0,0 +1,60 @@ +#include "sandbox_run_queue_fifo.h" +#include "sandbox_run_queue.h" + +__thread static struct ps_list_head sandbox_run_queue_fifo; + +bool +sandbox_run_queue_fifo_is_empty() +{ + return ps_list_head_empty(&sandbox_run_queue_fifo); +} + +// Get the sandbox at the head of the thread local runqueue +struct sandbox * +sandbox_run_queue_fifo_get_head() +{ + return ps_list_head_first_d(&sandbox_run_queue_fifo, struct sandbox); +} + +/** + * Removes the thread from the thread-local runqueue + * @param sandbox sandbox + **/ +void +sandbox_run_queue_fifo_remove(struct sandbox *sandbox_to_remove) +{ + ps_list_rem_d(sandbox_to_remove); +} + +// Append a sandbox to the runqueue +struct sandbox * +sandbox_run_queue_fifo_append(struct sandbox *sandbox_to_append) +{ + assert(ps_list_singleton_d(sandbox_to_append)); + // fprintf(stderr, "(%d,%lu) %s: run %p, %s\n", sched_getcpu(), pthread_self(), __func__, s, + // s->module->name); + ps_list_head_append_d(&sandbox_run_queue_fifo, sandbox_to_append); + return sandbox_to_append; +} + +struct sandbox * +sandbox_run_queue_fifo_remove_and_return() +{ + struct sandbox *sandbox_to_remove = ps_list_head_first_d(&sandbox_run_queue_fifo, struct sandbox); + ps_list_rem_d(sandbox_to_remove); + return sandbox_to_remove; +} + + +void +sandbox_run_queue_fifo_initialize() +{ + ps_list_head_init(&sandbox_run_queue_fifo); + + // Register Function Pointers for Abstract Scheduling API + sandbox_run_queue_config_t config = { .add = sandbox_run_queue_fifo_append, + .is_empty = sandbox_run_queue_fifo_is_empty, + .remove = sandbox_run_queue_fifo_remove_and_return }; + + sandbox_run_queue_initialize(&config); +} \ No newline at end of file diff --git a/runtime/src/sandbox_run_queue_ps.c b/runtime/src/sandbox_run_queue_ps.c new file mode 100644 index 0000000..ee20f2f --- /dev/null +++ b/runtime/src/sandbox_run_queue_ps.c @@ -0,0 +1,56 @@ +#include "sandbox_run_queue_ps.h" +#include "sandbox_run_queue.h" +#include "priority_queue.h" + +// Local State +__thread static struct priority_queue sandbox_run_queue_ps; + +bool +sandbox_run_queue_ps_is_empty() +{ + return priority_queue_length(&sandbox_run_queue_ps) == 0; +} + +/** + * Pushes a sandbox to the runqueue + * @param sandbox + * @returns pointer to request if added. NULL otherwise + **/ +static struct sandbox * +sandbox_run_queue_ps_add(struct sandbox *sandbox) +{ + int return_code = priority_queue_enqueue(&sandbox_run_queue_ps, sandbox); + + return return_code == 0 ? sandbox : NULL; +} + +/** + * + * @returns A Sandbox Request or NULL + **/ +static struct sandbox * +sandbox_run_queue_ps_remove(void) +{ + return (struct sandbox *)priority_queue_dequeue(&sandbox_run_queue_ps); +} + +unsigned long long int +sandbox_get_priority(void *element) +{ + struct sandbox *sandbox = (struct sandbox *)element; + return sandbox->absolute_deadline; +}; + +void +sandbox_run_queue_ps_initialize() +{ + // Initialize local state + priority_queue_initialize(&sandbox_run_queue_ps, sandbox_get_priority); + + // Register Function Pointers for Abstract Scheduling API + sandbox_run_queue_config_t config = { .add = sandbox_run_queue_ps_add, + .is_empty = sandbox_run_queue_ps_is_empty, + .remove = sandbox_run_queue_ps_remove }; + + sandbox_run_queue_initialize(&config); +}