You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.9 KiB

#include <stdint.h>
#include <threads.h>
#include "arch/context.h"
#include "client_socket.h"
#include "current_sandbox.h"
#include "debuglog.h"
#include "global_request_scheduler.h"
#include "local_runqueue.h"
#include "local_runqueue_minheap.h"
#include "panic.h"
#include "priority_queue.h"
#include "sandbox_functions.h"
#include "runtime.h"
thread_local static struct priority_queue *local_runqueue_minheap;
/**
* Checks if the run queue is empty
* @returns true if empty. false otherwise
*/
bool
local_runqueue_minheap_is_empty()
{
return priority_queue_length_nolock(local_runqueue_minheap) == 0;
}
/**
* Adds a sandbox to the run queue
* @param sandbox
* @returns pointer to sandbox added
*/
void
local_runqueue_minheap_add(struct sandbox *sandbox)
{
int return_code = priority_queue_enqueue_nolock(local_runqueue_minheap, sandbox);
if (unlikely(return_code == -ENOSPC)) {
struct priority_queue *temp = priority_queue_grow_nolock(local_runqueue_minheap);
if (unlikely(temp == NULL)) panic("Failed to grow local runqueue\n");
local_runqueue_minheap = temp;
return_code = priority_queue_enqueue_nolock(local_runqueue_minheap, sandbox);
if (unlikely(return_code == -ENOSPC)) panic("Thread Runqueue is full!\n");
}
}
/**
* Deletes a sandbox from the runqueue
* @param sandbox to delete
*/
static void
local_runqueue_minheap_delete(struct sandbox *sandbox)
{
assert(sandbox != NULL);
int rc = priority_queue_delete_nolock(local_runqueue_minheap, sandbox);
if (rc == -1) panic("Tried to delete sandbox %lu from runqueue, but was not present\n", sandbox->id);
}
/**
* This function determines the next sandbox to run.
* This is either the head of the runqueue or the head of the request queue
*
* 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_minheap_get_next()
{
/* Get the deadline of the sandbox at the head of the local request queue */
struct sandbox *next = NULL;
int rc = priority_queue_top_nolock(local_runqueue_minheap, (void **)&next);
if (rc == -ENOENT) return NULL;
return next;
}
/**
* Registers the PS variant with the polymorphic interface
*/
void
local_runqueue_minheap_initialize()
{
/* Initialize local state */
local_runqueue_minheap = priority_queue_initialize(RUNTIME_RUNQUEUE_SIZE, false, sandbox_get_priority);
/* Register Function Pointers for Abstract Scheduling API */
struct local_runqueue_config config = { .add_fn = local_runqueue_minheap_add,
.is_empty_fn = local_runqueue_minheap_is_empty,
.delete_fn = local_runqueue_minheap_delete,
.get_next_fn = local_runqueue_minheap_get_next };
local_runqueue_initialize(&config);
}