feat: implement PQ-based runqueue

main
Sean McBride 5 years ago
parent f5f9c168c6
commit 61c7ccea0c

@ -2,23 +2,24 @@
#define SFRT_SANDBOX_RUN_QUEUE_H #define SFRT_SANDBOX_RUN_QUEUE_H
#include <stdbool.h> #include <stdbool.h>
#include <sandbox.h>
#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 void sandbox_run_queue_initialize(sandbox_run_queue_config_t *config);
struct sandbox *sandbox_run_queue_get_head();
// Remove a sandbox from the runqueue struct sandbox *sandbox_run_queue_add(struct sandbox *);
void sandbox_run_queue_remove(struct sandbox *sandbox_to_remove); struct sandbox *sandbox_run_queue_remove();
bool sandbox_run_queue_is_empty();
/**
* Append the sandbox to the worker_thread_run_queue
* @param sandbox_to_append
*/
void sandbox_run_queue_append(struct sandbox *sandbox_to_append);
#endif /* SFRT_SANDBOX_RUN_QUEUE_H */ #endif /* SFRT_SANDBOX_RUN_QUEUE_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 */

@ -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 */

@ -24,6 +24,8 @@
// #include <sandbox_request_scheduler_fifo.h> // #include <sandbox_request_scheduler_fifo.h>
#include <sandbox_request_scheduler_ps.h> #include <sandbox_request_scheduler_ps.h>
#include <sandbox_run_queue.h> #include <sandbox_run_queue.h>
// #include <sandbox_run_queue_fifo.h>
#include <sandbox_run_queue_ps.h>
#include <software_interrupt.h> #include <software_interrupt.h>
#include <types.h> #include <types.h>
@ -205,7 +207,7 @@ worker_thread_wakeup_sandbox(sandbox_t *sandbox)
// debuglog("[%p: %s]\n", sandbox, sandbox->module->name); // debuglog("[%p: %s]\n", sandbox, sandbox->module->name);
if (sandbox->state == BLOCKED) { if (sandbox->state == BLOCKED) {
sandbox->state = RUNNABLE; sandbox->state = RUNNABLE;
sandbox_run_queue_append(sandbox); sandbox_run_queue_add(sandbox);
} }
software_interrupt_enable(); software_interrupt_enable();
} }
@ -287,7 +289,7 @@ worker_thread_pull_and_process_sandbox_requests(void)
free(sandbox_request); free(sandbox_request);
// Set the sandbox as runnable and place on the local runqueue // Set the sandbox as runnable and place on the local runqueue
sandbox->state = RUNNABLE; sandbox->state = RUNNABLE;
sandbox_run_queue_append(sandbox); sandbox_run_queue_add(sandbox);
total_sandboxes_pulled++; total_sandboxes_pulled++;
} }
@ -323,10 +325,9 @@ worker_thread_get_next_sandbox()
} }
// Execute Round Robin Scheduling Logic // 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); assert(next_sandbox->state != RETURNED);
sandbox_run_queue_remove(next_sandbox); sandbox_run_queue_add(next_sandbox);
sandbox_run_queue_append(next_sandbox);
debuglog("[%p: %s]\n", next_sandbox, next_sandbox->module->name); debuglog("[%p: %s]\n", next_sandbox, next_sandbox->module->name);
return next_sandbox; return next_sandbox;
@ -342,7 +343,10 @@ worker_thread_main(void *return_code)
{ {
// Initialize Worker State // Initialize Worker State
arch_context_init(&worker_thread_base_context, 0, 0); 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(); sandbox_completion_queue_initialize();
software_interrupt_is_disabled = false; software_interrupt_is_disabled = false;
worker_thread_next_context = NULL; worker_thread_next_context = NULL;

@ -1,42 +1,33 @@
#include "sandbox_run_queue.h" #include <sandbox_run_queue.h>
__thread static struct ps_list_head sandbox_run_queue;
void // The global of our polymorphic interface
sandbox_run_queue_initialize() static sandbox_run_queue_config_t sandbox_run_queue;
{
ps_list_head_init(&sandbox_run_queue);
}
bool // Initializes a concrete implementation of the sandbox request scheduler interface
sandbox_run_queue_is_empty() 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));
} }
// Adds a sandbox request
// Get the sandbox at the head of the thread local runqueue
struct sandbox * 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 a sandbox request
* Removes the thread from the thread-local runqueue struct sandbox *
* @param sandbox sandbox sandbox_run_queue_remove()
**/
void
sandbox_run_queue_remove(struct sandbox *sandbox_to_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 bool
void sandbox_run_queue_is_empty()
sandbox_run_queue_append(struct sandbox *sandbox_to_append)
{ {
assert(ps_list_singleton_d(sandbox_to_append)); return sandbox_run_queue_is_empty();
// 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);
} }

@ -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);
}

@ -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);
}
Loading…
Cancel
Save