#include "global_request_scheduler.h" #include "global_request_scheduler_deque.h" #include "runtime.h" #define GLOBAL_REQUEST_SCHEDULER_DEQUE_CAPACITY (1 << 19) static struct deque_sandbox *global_request_scheduler_deque; /* TODO: Should this be used??? */ static pthread_mutex_t global_request_scheduler_deque_mutex = PTHREAD_MUTEX_INITIALIZER; /** * Pushes a sandbox to the global deque * @param sandbox_raw * @returns pointer to sandbox if added. NULL otherwise */ static struct sandbox * global_request_scheduler_deque_add(struct sandbox *sandbox) { int return_code = 1; return_code = deque_push_sandbox(global_request_scheduler_deque, &sandbox); if (return_code != 0) return NULL; return sandbox; } /** * Stealing from the dequeue is a lock-free, cross-core "pop", which removes the element from the end opposite to * "pop". Because the producer and consumer (the core stealine the sandbox) modify different ends, * no locks are required, and coordination is achieved by instead retrying on inconsistent indices. * * Relevant Read: https://www.dre.vanderbilt.edu/~schmidt/PDF/work-stealing-dequeue.pdf * * @returns 0 if successfully returned a sandbox, -ENOENT if empty, -EAGAIN if atomic instruction unsuccessful */ static int global_request_scheduler_deque_remove(struct sandbox **removed_sandbox) { return deque_steal_sandbox(global_request_scheduler_deque, removed_sandbox); } static int global_request_scheduler_deque_remove_if_earlier(struct sandbox **removed_sandbox, uint64_t target_deadline) { panic("Deque variant does not support this call\n"); return -1; } void global_request_scheduler_deque_initialize() { /* Allocate and Initialize the global deque */ global_request_scheduler_deque = (struct deque_sandbox *)calloc(1, sizeof(struct deque_sandbox)); assert(global_request_scheduler_deque); /* Note: Below is a Macro */ deque_init_sandbox(global_request_scheduler_deque, GLOBAL_REQUEST_SCHEDULER_DEQUE_CAPACITY); /* Register Function Pointers for Abstract Scheduling API */ struct global_request_scheduler_config config = { .add_fn = global_request_scheduler_deque_add, .remove_fn = global_request_scheduler_deque_remove, .remove_if_earlier_fn = global_request_scheduler_deque_remove_if_earlier }; global_request_scheduler_initialize(&config); }