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

@ -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_ps.h>
#include <sandbox_run_queue.h>
// #include <sandbox_run_queue_fifo.h>
#include <sandbox_run_queue_ps.h>
#include <software_interrupt.h>
#include <types.h>
@ -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;

@ -1,42 +1,33 @@
#include "sandbox_run_queue.h"
#include <sandbox_run_queue.h>
__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();
}

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