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.

91 lines
2.5 KiB

#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <sched.h>
#include <stdlib.h>
#include "current_sandbox.h"
#include "local_completion_queue.h"
#include "local_runqueue.h"
#include "local_runqueue_list.h"
#include "local_runqueue_minheap.h"
#include "panic.h"
#include "runtime.h"
#include "scheduler.h"
#include "worker_thread.h"
#include "worker_thread_execute_epoll_loop.h"
/***************************
* Worker Thread State *
**************************/
/* context of the runtime thread before running sandboxes or to resume its "main". */
__thread struct arch_context worker_thread_base_context;
__thread int worker_thread_epoll_file_descriptor;
/* Used to index into global arguments and deadlines arrays */
__thread int worker_thread_idx;
/***********************
* Worker Thread Logic *
**********************/
/**
* The entry function for sandbox worker threads
* Initializes thread-local state, unmasks signals, sets up epoll loop and
* @param argument - argument provided by pthread API. We set to -1 on error
*/
void *
worker_thread_main(void *argument)
{
/* The base worker thread should start with software interrupts disabled */
assert(software_interrupt_is_disabled);
/* Set base context as running */
worker_thread_base_context.variant = ARCH_CONTEXT_VARIANT_RUNNING;
/* Index was passed via argument */
worker_thread_idx = *(int *)argument;
/* Set my priority */
// runtime_set_pthread_prio(pthread_self(), 0);
scheduler_runqueue_initialize();
/* Initialize Completion Queue */
local_completion_queue_initialize();
/* Initialize epoll */
worker_thread_epoll_file_descriptor = epoll_create1(0);
if (unlikely(worker_thread_epoll_file_descriptor < 0)) panic_err();
/* Unmask signals, unless the runtime has disabled preemption */
if (runtime_preemption_enabled) {
software_interrupt_unmask_signal(SIGALRM);
software_interrupt_unmask_signal(SIGUSR1);
}
/* Begin Worker Execution Loop */
struct sandbox *next_sandbox = NULL;
while (true) {
assert(!software_interrupt_is_enabled());
/* Assumption: current_sandbox should be unset at start of loop */
assert(current_sandbox_get() == NULL);
worker_thread_execute_epoll_loop();
/* Switch to a sandbox if one is ready to run */
next_sandbox = scheduler_get_next();
if (next_sandbox != NULL) { scheduler_switch_to(next_sandbox); }
assert(!software_interrupt_is_enabled());
/* Clear the completion queue */
local_completion_queue_free();
}
panic("Worker Thread unexpectedly completed run loop.");
}