parent
0eb474a8d7
commit
1c2aa448cd
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <sandbox_request.h>
|
||||
|
||||
/* Returns pointer back if successful, null otherwise */
|
||||
typedef sandbox_request_t *(*global_request_scheduler_add_fn_t)(void *);
|
||||
typedef sandbox_request_t *(*global_request_scheduler_remove_fn_t)(void);
|
||||
typedef uint64_t (*global_request_scheduler_peek_fn_t)(void);
|
||||
|
||||
struct global_request_scheduler_config {
|
||||
global_request_scheduler_add_fn_t add_fn;
|
||||
global_request_scheduler_remove_fn_t remove_fn;
|
||||
global_request_scheduler_peek_fn_t peek_fn;
|
||||
};
|
||||
|
||||
|
||||
void global_request_scheduler_initialize(struct global_request_scheduler_config *config);
|
||||
|
||||
sandbox_request_t *global_request_scheduler_add(sandbox_request_t *);
|
||||
sandbox_request_t *global_request_scheduler_remove();
|
||||
uint64_t global_request_scheduler_peek();
|
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <global_request_scheduler.h>
|
||||
|
||||
void global_request_scheduler_deque_initialize();
|
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <global_request_scheduler.h>
|
||||
|
||||
void global_request_scheduler_minheap_initialize();
|
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "sandbox.h"
|
||||
|
||||
void local_completion_queue_add(struct sandbox *sandbox);
|
||||
void local_completion_queue_free();
|
||||
void local_completion_queue_initialize();
|
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sandbox.h>
|
||||
|
||||
/* Returns pointer back if successful, null otherwise */
|
||||
typedef struct sandbox *(*local_runqueue_add_fn_t)(struct sandbox *);
|
||||
typedef bool (*local_runqueue_is_empty_fn_t)(void);
|
||||
typedef void (*local_runqueue_delete_fn_t)(struct sandbox *sandbox);
|
||||
typedef struct sandbox *(*local_runqueue_get_next_fn_t)();
|
||||
typedef void (*local_runqueue_preempt_fn_t)(ucontext_t *);
|
||||
|
||||
struct local_runqueue_config {
|
||||
local_runqueue_add_fn_t add_fn;
|
||||
local_runqueue_is_empty_fn_t is_empty_fn;
|
||||
local_runqueue_delete_fn_t delete_fn;
|
||||
local_runqueue_get_next_fn_t get_next_fn;
|
||||
local_runqueue_preempt_fn_t preempt_fn;
|
||||
};
|
||||
|
||||
void local_runqueue_initialize(struct local_runqueue_config *config);
|
||||
|
||||
/* This is currently only used by worker_thread_wakeup_sandbox */
|
||||
struct sandbox *local_runqueue_add(struct sandbox *);
|
||||
void local_runqueue_delete(struct sandbox *);
|
||||
bool local_runqueue_is_empty();
|
||||
struct sandbox *local_runqueue_get_next();
|
||||
void local_runqueue_preempt(ucontext_t *);
|
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "sandbox.h"
|
||||
|
||||
void local_runqueue_list_initialize();
|
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "sandbox.h"
|
||||
|
||||
void local_runqueue_minheap_initialize();
|
@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "sandbox.h"
|
||||
|
||||
void sandbox_completion_queue_add(struct sandbox *sandbox);
|
||||
void sandbox_completion_queue_free();
|
||||
void sandbox_completion_queue_initialize();
|
@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <sandbox_request.h>
|
||||
|
||||
/* Returns pointer back if successful, null otherwise */
|
||||
typedef sandbox_request_t *(*sandbox_request_scheduler_add_fn_t)(void *);
|
||||
typedef sandbox_request_t *(*sandbox_request_scheduler_remove_fn_t)(void);
|
||||
typedef uint64_t (*sandbox_request_scheduler_peek_fn_t)(void);
|
||||
|
||||
typedef struct sandbox_request_scheduler_config {
|
||||
sandbox_request_scheduler_add_fn_t add;
|
||||
sandbox_request_scheduler_remove_fn_t remove;
|
||||
sandbox_request_scheduler_peek_fn_t peek;
|
||||
} sandbox_request_scheduler_config_t;
|
||||
|
||||
|
||||
void sandbox_request_scheduler_initialize(sandbox_request_scheduler_config_t *config);
|
||||
|
||||
sandbox_request_t *sandbox_request_scheduler_add(sandbox_request_t *);
|
||||
sandbox_request_t *sandbox_request_scheduler_remove();
|
||||
uint64_t sandbox_request_scheduler_peek();
|
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <sandbox_request_scheduler.h>
|
||||
|
||||
void sandbox_request_scheduler_fifo_initialize();
|
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <sandbox_request_scheduler.h>
|
||||
|
||||
void sandbox_request_scheduler_ps_initialize();
|
@ -1,30 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sandbox.h>
|
||||
|
||||
/* Returns pointer back if successful, null otherwise */
|
||||
typedef struct sandbox *(*sandbox_run_queue_add_fn_t)(struct sandbox *);
|
||||
typedef bool (*sandbox_run_queue_is_empty_fn_t)(void);
|
||||
typedef void (*sandbox_run_queue_delete_fn_t)(struct sandbox *sandbox);
|
||||
typedef struct sandbox *(*sandbox_run_queue_get_next_fn_t)();
|
||||
typedef void (*sandbox_run_queue_preempt_fn_t)(ucontext_t *);
|
||||
|
||||
typedef struct sandbox_run_queue_config {
|
||||
sandbox_run_queue_add_fn_t add;
|
||||
sandbox_run_queue_is_empty_fn_t is_empty;
|
||||
sandbox_run_queue_delete_fn_t delete;
|
||||
sandbox_run_queue_get_next_fn_t get_next;
|
||||
sandbox_run_queue_preempt_fn_t preempt;
|
||||
} sandbox_run_queue_config_t;
|
||||
|
||||
|
||||
void sandbox_run_queue_initialize(sandbox_run_queue_config_t *config);
|
||||
|
||||
|
||||
/* This is currently only used by worker_thread_wakeup_sandbox */
|
||||
struct sandbox *sandbox_run_queue_add(struct sandbox *);
|
||||
void sandbox_run_queue_delete(struct sandbox *);
|
||||
bool sandbox_run_queue_is_empty();
|
||||
struct sandbox *sandbox_run_queue_get_next();
|
||||
void sandbox_run_queue_preempt(ucontext_t *);
|
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "sandbox.h"
|
||||
|
||||
void sandbox_run_queue_fifo_initialize();
|
@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "sandbox.h"
|
||||
|
||||
void sandbox_run_queue_ps_initialize();
|
@ -0,0 +1,49 @@
|
||||
#include <global_request_scheduler.h>
|
||||
|
||||
|
||||
/* The global of our polymorphic interface */
|
||||
static struct global_request_scheduler_config global_request_scheduler;
|
||||
|
||||
/**
|
||||
* Initializes the polymorphic interface with a concrete implementation
|
||||
* @param config
|
||||
*/
|
||||
void
|
||||
global_request_scheduler_initialize(struct global_request_scheduler_config *config)
|
||||
{
|
||||
memcpy(&global_request_scheduler, config, sizeof(struct global_request_scheduler_config));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a sandbox request to the request scheduler
|
||||
* @param sandbox_request
|
||||
*/
|
||||
sandbox_request_t *
|
||||
global_request_scheduler_add(sandbox_request_t *sandbox_request)
|
||||
{
|
||||
assert(global_request_scheduler.add_fn != NULL);
|
||||
return global_request_scheduler.add_fn(sandbox_request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a sandbox request according to the scheduling policy of the variant
|
||||
* @returns pointer to a sandbox request
|
||||
*/
|
||||
sandbox_request_t *
|
||||
global_request_scheduler_remove()
|
||||
{
|
||||
assert(global_request_scheduler.remove_fn != NULL);
|
||||
return global_request_scheduler.remove_fn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks at the priority of the highest priority sandbox request
|
||||
* @returns highest priority
|
||||
*/
|
||||
uint64_t
|
||||
global_request_scheduler_peek()
|
||||
{
|
||||
assert(global_request_scheduler.peek_fn != NULL);
|
||||
return global_request_scheduler.peek_fn();
|
||||
};
|
@ -0,0 +1,66 @@
|
||||
#include <global_request_scheduler.h>
|
||||
#include "priority_queue.h"
|
||||
|
||||
static struct priority_queue global_request_scheduler_minheap;
|
||||
|
||||
/**
|
||||
* Pushes a sandbox request to the global deque
|
||||
* @param sandbox_request
|
||||
* @returns pointer to request if added. NULL otherwise
|
||||
*/
|
||||
static sandbox_request_t *
|
||||
global_request_scheduler_minheap_add(void *sandbox_request)
|
||||
{
|
||||
int return_code = priority_queue_enqueue(&global_request_scheduler_minheap, sandbox_request, "Request");
|
||||
|
||||
if (return_code == -1) {
|
||||
printf("Request Queue is full\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (return_code != 0) return NULL;
|
||||
return sandbox_request;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns A Sandbox Request or NULL
|
||||
*/
|
||||
static sandbox_request_t *
|
||||
global_request_scheduler_minheap_remove(void)
|
||||
{
|
||||
return (sandbox_request_t *)priority_queue_dequeue(&global_request_scheduler_minheap, "Request");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns A Sandbox Request or NULL
|
||||
*/
|
||||
static uint64_t
|
||||
global_request_scheduler_minheap_peek(void)
|
||||
{
|
||||
return priority_queue_peek(&global_request_scheduler_minheap);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
sandbox_request_get_priority_fn(void *element)
|
||||
{
|
||||
sandbox_request_t *sandbox_request = (sandbox_request_t *)element;
|
||||
return sandbox_request->absolute_deadline;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the variant and registers against the polymorphic interface
|
||||
*/
|
||||
void
|
||||
global_request_scheduler_minheap_initialize()
|
||||
{
|
||||
priority_queue_initialize(&global_request_scheduler_minheap, sandbox_request_get_priority_fn);
|
||||
|
||||
struct global_request_scheduler_config config = { .add_fn = global_request_scheduler_minheap_add,
|
||||
.remove_fn = global_request_scheduler_minheap_remove,
|
||||
.peek_fn = global_request_scheduler_minheap_peek };
|
||||
|
||||
global_request_scheduler_initialize(&config);
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
#include "local_completion_queue.h"
|
||||
|
||||
__thread static struct ps_list_head local_completion_queue;
|
||||
|
||||
|
||||
void
|
||||
local_completion_queue_initialize()
|
||||
{
|
||||
ps_list_head_init(&local_completion_queue);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
local_completion_queue_is_empty()
|
||||
{
|
||||
return ps_list_head_empty(&local_completion_queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds sandbox to the completion queue
|
||||
* @param sandbox to add to completion queue
|
||||
*/
|
||||
void
|
||||
local_completion_queue_add(struct sandbox *sandbox)
|
||||
{
|
||||
assert(sandbox);
|
||||
assert(ps_list_singleton_d(sandbox));
|
||||
ps_list_head_append_d(&local_completion_queue, sandbox);
|
||||
assert(!local_completion_queue_is_empty());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Frees all sandboxes in the thread local completion queue
|
||||
* @return void
|
||||
*/
|
||||
void
|
||||
local_completion_queue_free()
|
||||
{
|
||||
struct sandbox *sandbox_iterator;
|
||||
struct sandbox *buffer;
|
||||
|
||||
ps_list_foreach_del_d(&local_completion_queue, sandbox_iterator, buffer)
|
||||
{
|
||||
ps_list_rem_d(sandbox_iterator);
|
||||
sandbox_free(sandbox_iterator);
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
#include <local_runqueue.h>
|
||||
|
||||
static struct local_runqueue_config local_runqueue;
|
||||
|
||||
/* Initializes a concrete implementation of the sandbox request scheduler interface */
|
||||
void
|
||||
local_runqueue_initialize(struct local_runqueue_config *config)
|
||||
{
|
||||
memcpy(&local_runqueue, config, sizeof(struct local_runqueue_config));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a sandbox request to the run queue
|
||||
* @param sandbox to add
|
||||
* @returns sandbox that was added (or NULL?)
|
||||
*/
|
||||
struct sandbox *
|
||||
local_runqueue_add(struct sandbox *sandbox)
|
||||
{
|
||||
assert(local_runqueue.add_fn != NULL);
|
||||
return local_runqueue.add_fn(sandbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a sandbox from the run queue
|
||||
* @param sandbox to delete
|
||||
*/
|
||||
void
|
||||
local_runqueue_delete(struct sandbox *sandbox)
|
||||
{
|
||||
assert(local_runqueue.delete_fn != NULL);
|
||||
local_runqueue.delete_fn(sandbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if run queue is empty
|
||||
* @returns true if empty
|
||||
*/
|
||||
bool
|
||||
local_runqueue_is_empty()
|
||||
{
|
||||
assert(local_runqueue.is_empty_fn != NULL);
|
||||
return local_runqueue.is_empty_fn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next sandbox from run queue, where next is defined by
|
||||
* @returns sandbox (or NULL?)
|
||||
*/
|
||||
struct sandbox *
|
||||
local_runqueue_get_next()
|
||||
{
|
||||
assert(local_runqueue.get_next_fn != NULL);
|
||||
return local_runqueue.get_next_fn();
|
||||
};
|
||||
|
||||
/**
|
||||
* Preempt the current sandbox according to the scheduler variant
|
||||
* @param context
|
||||
*/
|
||||
void
|
||||
local_runqueue_preempt(ucontext_t *context)
|
||||
{
|
||||
assert(local_runqueue.preempt_fn != NULL);
|
||||
return local_runqueue.preempt_fn(context);
|
||||
};
|
@ -0,0 +1,103 @@
|
||||
#include "local_runqueue_list.h"
|
||||
#include "local_runqueue.h"
|
||||
#include "global_request_scheduler.h"
|
||||
|
||||
__thread static struct ps_list_head local_runqueue_list;
|
||||
|
||||
bool
|
||||
local_runqueue_list_is_empty()
|
||||
{
|
||||
return ps_list_head_empty(&local_runqueue_list);
|
||||
}
|
||||
|
||||
/* Get the sandbox at the head of the thread local runqueue */
|
||||
struct sandbox *
|
||||
local_runqueue_list_get_head()
|
||||
{
|
||||
return ps_list_head_first_d(&local_runqueue_list, struct sandbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the thread from the thread-local runqueue
|
||||
* @param sandbox sandbox
|
||||
*/
|
||||
void
|
||||
local_runqueue_list_remove(struct sandbox *sandbox_to_remove)
|
||||
{
|
||||
ps_list_rem_d(sandbox_to_remove);
|
||||
}
|
||||
|
||||
struct sandbox *
|
||||
local_runqueue_list_remove_and_return()
|
||||
{
|
||||
struct sandbox *sandbox_to_remove = ps_list_head_first_d(&local_runqueue_list, struct sandbox);
|
||||
ps_list_rem_d(sandbox_to_remove);
|
||||
return sandbox_to_remove;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the sandbox at the head of the thread local runqueue
|
||||
* If the runqueue is empty, pull a fresh batch of sandbox requests, instantiate them, and then execute the new head
|
||||
* @return the sandbox to execute or NULL if none are available
|
||||
*/
|
||||
struct sandbox *
|
||||
local_runqueue_list_get_next()
|
||||
{
|
||||
if (local_runqueue_is_empty()) {
|
||||
sandbox_request_t *sandbox_request = global_request_scheduler_remove();
|
||||
if (sandbox_request == NULL) return NULL;
|
||||
struct sandbox *sandbox = sandbox_allocate(sandbox_request);
|
||||
assert(sandbox);
|
||||
free(sandbox_request);
|
||||
sandbox->state = RUNNABLE;
|
||||
local_runqueue_add(sandbox);
|
||||
return sandbox;
|
||||
}
|
||||
|
||||
/* Execute Round Robin Scheduling Logic */
|
||||
struct sandbox *next_sandbox = local_runqueue_list_remove_and_return();
|
||||
assert(next_sandbox->state != RETURNED);
|
||||
local_runqueue_add(next_sandbox);
|
||||
|
||||
debuglog("[%p: %s]\n", next_sandbox, next_sandbox->module->name);
|
||||
return next_sandbox;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Append a sandbox to the runqueue
|
||||
* @returns the appended sandbox
|
||||
*/
|
||||
struct sandbox *
|
||||
local_runqueue_list_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(&local_runqueue_list, sandbox_to_append);
|
||||
return sandbox_to_append;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally checks to see if current sandbox should be preempted FIFO doesn't preempt, so just return.
|
||||
*/
|
||||
void
|
||||
local_runqueue_list_preempt(ucontext_t *user_context)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
local_runqueue_list_initialize()
|
||||
{
|
||||
ps_list_head_init(&local_runqueue_list);
|
||||
|
||||
/* Register Function Pointers for Abstract Scheduling API */
|
||||
struct local_runqueue_config config = { .add_fn = local_runqueue_list_append,
|
||||
.is_empty_fn = local_runqueue_list_is_empty,
|
||||
.delete_fn = local_runqueue_list_remove,
|
||||
.get_next_fn = local_runqueue_list_get_next,
|
||||
.preempt_fn = local_runqueue_list_preempt };
|
||||
local_runqueue_initialize(&config);
|
||||
};
|
@ -1,47 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
sandbox_completion_queue_is_empty()
|
||||
{
|
||||
return ps_list_head_empty(&sandbox_completion_queue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds sandbox to the completion queue
|
||||
* @param sandbox to add to completion queue
|
||||
*/
|
||||
void
|
||||
sandbox_completion_queue_add(struct sandbox *sandbox)
|
||||
{
|
||||
assert(sandbox);
|
||||
assert(ps_list_singleton_d(sandbox));
|
||||
ps_list_head_append_d(&sandbox_completion_queue, sandbox);
|
||||
assert(!sandbox_completion_queue_is_empty());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Frees all sandboxes in the thread local completion queue
|
||||
* @return void
|
||||
*/
|
||||
void
|
||||
sandbox_completion_queue_free()
|
||||
{
|
||||
struct sandbox *sandbox_iterator;
|
||||
struct sandbox *buffer;
|
||||
|
||||
ps_list_foreach_del_d(&sandbox_completion_queue, sandbox_iterator, buffer)
|
||||
{
|
||||
ps_list_rem_d(sandbox_iterator);
|
||||
sandbox_free(sandbox_iterator);
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
#include <sandbox_request_scheduler.h>
|
||||
|
||||
|
||||
/* The global of our polymorphic interface */
|
||||
static sandbox_request_scheduler_config_t sandbox_request_scheduler;
|
||||
|
||||
/**
|
||||
* Initializes the polymorphic interface with a concrete implementation
|
||||
* @param config
|
||||
*/
|
||||
void
|
||||
sandbox_request_scheduler_initialize(sandbox_request_scheduler_config_t *config)
|
||||
{
|
||||
memcpy(&sandbox_request_scheduler, config, sizeof(sandbox_request_scheduler_config_t));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a sandbox request to the request scheduler
|
||||
* @param sandbox_request
|
||||
*/
|
||||
sandbox_request_t *
|
||||
sandbox_request_scheduler_add(sandbox_request_t *sandbox_request)
|
||||
{
|
||||
assert(sandbox_request_scheduler.add != NULL);
|
||||
return sandbox_request_scheduler.add(sandbox_request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a sandbox request according to the scheduling policy of the variant
|
||||
* @returns pointer to a sandbox request
|
||||
*/
|
||||
sandbox_request_t *
|
||||
sandbox_request_scheduler_remove()
|
||||
{
|
||||
assert(sandbox_request_scheduler.remove != NULL);
|
||||
return sandbox_request_scheduler.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Peeks at the priority of the highest priority sandbox request
|
||||
* @returns highest priority
|
||||
*/
|
||||
uint64_t
|
||||
sandbox_request_scheduler_peek()
|
||||
{
|
||||
assert(sandbox_request_scheduler.peek != NULL);
|
||||
return sandbox_request_scheduler.peek();
|
||||
};
|
@ -1,66 +0,0 @@
|
||||
#include <sandbox_request_scheduler.h>
|
||||
#include "priority_queue.h"
|
||||
|
||||
static struct priority_queue sandbox_request_scheduler_ps;
|
||||
|
||||
/**
|
||||
* Pushes a sandbox request to the global deque
|
||||
* @param sandbox_request
|
||||
* @returns pointer to request if added. NULL otherwise
|
||||
*/
|
||||
static sandbox_request_t *
|
||||
sandbox_request_scheduler_ps_add(void *sandbox_request)
|
||||
{
|
||||
int return_code = priority_queue_enqueue(&sandbox_request_scheduler_ps, sandbox_request, "Request");
|
||||
|
||||
if (return_code == -1) {
|
||||
printf("Request Queue is full\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (return_code != 0) return NULL;
|
||||
return sandbox_request;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns A Sandbox Request or NULL
|
||||
*/
|
||||
static sandbox_request_t *
|
||||
sandbox_request_scheduler_ps_remove(void)
|
||||
{
|
||||
return (sandbox_request_t *)priority_queue_dequeue(&sandbox_request_scheduler_ps, "Request");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns A Sandbox Request or NULL
|
||||
*/
|
||||
static uint64_t
|
||||
sandbox_request_scheduler_ps_peek(void)
|
||||
{
|
||||
return priority_queue_peek(&sandbox_request_scheduler_ps);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
sandbox_request_get_priority_fn(void *element)
|
||||
{
|
||||
sandbox_request_t *sandbox_request = (sandbox_request_t *)element;
|
||||
return sandbox_request->absolute_deadline;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the variant and registers against the polymorphic interface
|
||||
*/
|
||||
void
|
||||
sandbox_request_scheduler_ps_initialize()
|
||||
{
|
||||
priority_queue_initialize(&sandbox_request_scheduler_ps, sandbox_request_get_priority_fn);
|
||||
|
||||
sandbox_request_scheduler_config_t config = { .add = sandbox_request_scheduler_ps_add,
|
||||
.remove = sandbox_request_scheduler_ps_remove,
|
||||
.peek = sandbox_request_scheduler_ps_peek };
|
||||
|
||||
sandbox_request_scheduler_initialize(&config);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
#include <sandbox_run_queue.h>
|
||||
|
||||
static sandbox_run_queue_config_t sandbox_run_queue;
|
||||
|
||||
/* Initializes a concrete implementation of the sandbox request scheduler interface */
|
||||
void
|
||||
sandbox_run_queue_initialize(sandbox_run_queue_config_t *config)
|
||||
{
|
||||
memcpy(&sandbox_run_queue, config, sizeof(sandbox_run_queue_config_t));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a sandbox request to the run queue
|
||||
* @param sandbox to add
|
||||
* @returns sandbox that was added (or NULL?)
|
||||
*/
|
||||
struct sandbox *
|
||||
sandbox_run_queue_add(struct sandbox *sandbox)
|
||||
{
|
||||
assert(sandbox_run_queue.add != NULL);
|
||||
return sandbox_run_queue.add(sandbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a sandbox from the run queue
|
||||
* @param sandbox to delete
|
||||
*/
|
||||
void
|
||||
sandbox_run_queue_delete(struct sandbox *sandbox)
|
||||
{
|
||||
assert(sandbox_run_queue.delete != NULL);
|
||||
sandbox_run_queue.delete(sandbox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if run queue is empty
|
||||
* @returns true if empty
|
||||
*/
|
||||
bool
|
||||
sandbox_run_queue_is_empty()
|
||||
{
|
||||
assert(sandbox_run_queue.is_empty != NULL);
|
||||
return sandbox_run_queue.is_empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next sandbox from run queue, where next is defined by
|
||||
* @returns sandbox (or NULL?)
|
||||
*/
|
||||
struct sandbox *
|
||||
sandbox_run_queue_get_next()
|
||||
{
|
||||
assert(sandbox_run_queue.get_next != NULL);
|
||||
return sandbox_run_queue.get_next();
|
||||
};
|
||||
|
||||
/**
|
||||
* Preempt the current sandbox according to the scheduler variant
|
||||
* @param context
|
||||
*/
|
||||
void
|
||||
sandbox_run_queue_preempt(ucontext_t *context)
|
||||
{
|
||||
assert(sandbox_run_queue.preempt != NULL);
|
||||
return sandbox_run_queue.preempt(context);
|
||||
};
|
@ -1,103 +0,0 @@
|
||||
#include "sandbox_run_queue_fifo.h"
|
||||
#include "sandbox_run_queue.h"
|
||||
#include "sandbox_request_scheduler.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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the sandbox at the head of the thread local runqueue
|
||||
* If the runqueue is empty, pull a fresh batch of sandbox requests, instantiate them, and then execute the new head
|
||||
* @return the sandbox to execute or NULL if none are available
|
||||
*/
|
||||
struct sandbox *
|
||||
sandbox_run_queue_fifo_get_next()
|
||||
{
|
||||
if (sandbox_run_queue_is_empty()) {
|
||||
sandbox_request_t *sandbox_request = sandbox_request_scheduler_remove();
|
||||
if (sandbox_request == NULL) return NULL;
|
||||
struct sandbox *sandbox = sandbox_allocate(sandbox_request);
|
||||
assert(sandbox);
|
||||
free(sandbox_request);
|
||||
sandbox->state = RUNNABLE;
|
||||
sandbox_run_queue_add(sandbox);
|
||||
return sandbox;
|
||||
}
|
||||
|
||||
/* Execute Round Robin Scheduling Logic */
|
||||
struct sandbox *next_sandbox = sandbox_run_queue_fifo_remove_and_return();
|
||||
assert(next_sandbox->state != RETURNED);
|
||||
sandbox_run_queue_add(next_sandbox);
|
||||
|
||||
debuglog("[%p: %s]\n", next_sandbox, next_sandbox->module->name);
|
||||
return next_sandbox;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Append a sandbox to the runqueue
|
||||
* @returns the appended sandbox
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally checks to see if current sandbox should be preempted FIFO doesn't preempt, so just return.
|
||||
*/
|
||||
void
|
||||
sandbox_run_queue_fifo_preempt(ucontext_t *user_context)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
.delete = sandbox_run_queue_fifo_remove,
|
||||
.get_next = sandbox_run_queue_fifo_get_next,
|
||||
.preempt = sandbox_run_queue_fifo_preempt };
|
||||
sandbox_run_queue_initialize(&config);
|
||||
};
|
Loading…
Reference in new issue