From 996c1479281cde89ecca44ecc8c83d5b44bebd41 Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Thu, 30 Apr 2020 19:19:40 -0400 Subject: [PATCH] fix: correct runqueue cleanup bug --- post_body.txt | 1 + post_body2.txt | 1 + runtime/include/priority_queue.h | 14 ++++---- runtime/include/sandbox_request_scheduler.h | 3 ++ runtime/include/sandbox_run_queue.h | 3 ++ runtime/include/sandbox_run_queue_ps.h | 6 ++-- runtime/src/priority_queue.c | 36 +++++++++++++++++++-- runtime/src/runtime.c | 2 +- runtime/src/sandbox_request_scheduler_ps.c | 15 +++++++-- runtime/src/sandbox_run_queue.c | 7 ++++ runtime/src/sandbox_run_queue_fifo.c | 3 +- runtime/src/sandbox_run_queue_ps.c | 17 ++++++++-- runtime/src/worker_thread.c | 10 +++--- 13 files changed, 95 insertions(+), 23 deletions(-) create mode 100644 post_body.txt create mode 100644 post_body2.txt diff --git a/post_body.txt b/post_body.txt new file mode 100644 index 0000000..86ee83a --- /dev/null +++ b/post_body.txt @@ -0,0 +1 @@ +40 \ No newline at end of file diff --git a/post_body2.txt b/post_body2.txt new file mode 100644 index 0000000..9a03714 --- /dev/null +++ b/post_body2.txt @@ -0,0 +1 @@ +10 \ No newline at end of file diff --git a/runtime/include/priority_queue.h b/runtime/include/priority_queue.h index 08d93c4..ca43bb4 100644 --- a/runtime/include/priority_queue.h +++ b/runtime/include/priority_queue.h @@ -13,20 +13,22 @@ * @param element * @returns priority (a u64) **/ -typedef unsigned long long int (*priority_queue_get_priority_t)(void *element); +typedef uint64_t (*priority_queue_get_priority_t)(void *element); // We assume that priority is expressed in terms of a 64 bit unsigned integral struct priority_queue { ck_spinlock_fas_t lock; - unsigned long long int highest_priority; + uint64_t highest_priority; void * items[MAX]; int first_free; priority_queue_get_priority_t get_priority; }; -void priority_queue_initialize(struct priority_queue *self, priority_queue_get_priority_t get_priority); -int priority_queue_enqueue(struct priority_queue *self, void *value); -void *priority_queue_dequeue(struct priority_queue *self); -int priority_queue_length(struct priority_queue *self); +void priority_queue_initialize(struct priority_queue *self, priority_queue_get_priority_t get_priority); +int priority_queue_enqueue(struct priority_queue *self, void *value); +void * priority_queue_dequeue(struct priority_queue *self); +int priority_queue_length(struct priority_queue *self); +uint64_t priority_queue_peek(struct priority_queue *self); +int priority_queue_delete(struct priority_queue *self, void *value); #endif /* PRIORITY_QUEUE_H */ \ No newline at end of file diff --git a/runtime/include/sandbox_request_scheduler.h b/runtime/include/sandbox_request_scheduler.h index fbc3a4a..efeb1a2 100644 --- a/runtime/include/sandbox_request_scheduler.h +++ b/runtime/include/sandbox_request_scheduler.h @@ -6,10 +6,12 @@ // Returns pointer back if successful, null otherwise typedef sandbox_request_t *(*sandbox_request_scheduler_add_t)(void *); typedef sandbox_request_t *(*sandbox_request_scheduler_remove_t)(void); +typedef uint64_t (*sandbox_request_scheduler_peek_t)(void); typedef struct sandbox_request_scheduler_config_t { sandbox_request_scheduler_add_t add; sandbox_request_scheduler_remove_t remove; + sandbox_request_scheduler_peek_t peek; } sandbox_request_scheduler_config_t; @@ -17,5 +19,6 @@ void sandbox_request_scheduler_initialize(sandbox_request_scheduler_config_t *co sandbox_request_t *sandbox_request_scheduler_add(sandbox_request_t *); sandbox_request_t *sandbox_request_scheduler_remove(); +uint64_t sandbox_request_scheduler_peek(); #endif /* SFRT_SANDBOX_REQUEST_QUEUE_H */ \ No newline at end of file diff --git a/runtime/include/sandbox_run_queue.h b/runtime/include/sandbox_run_queue.h index 486b298..873ae45 100644 --- a/runtime/include/sandbox_run_queue.h +++ b/runtime/include/sandbox_run_queue.h @@ -8,17 +8,20 @@ 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); +typedef void (*sandbox_run_queue_delete_t)(struct sandbox *sandbox); 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_delete_t delete; } sandbox_run_queue_config_t; void sandbox_run_queue_initialize(sandbox_run_queue_config_t *config); struct sandbox *sandbox_run_queue_add(struct sandbox *); +void sandbox_run_queue_delete(struct sandbox *); struct sandbox *sandbox_run_queue_remove(); bool sandbox_run_queue_is_empty(); diff --git a/runtime/include/sandbox_run_queue_ps.h b/runtime/include/sandbox_run_queue_ps.h index 196cb74..3ec0d1e 100644 --- a/runtime/include/sandbox_run_queue_ps.h +++ b/runtime/include/sandbox_run_queue_ps.h @@ -1,8 +1,8 @@ -#ifndef SFRT_SANDBOX_RUN_QUEUE_FIFO_H -#define SFRT_SANDBOX_RUN_QUEUE_FIFO_H +#ifndef SFRT_SANDBOX_RUN_QUEUE_PS_H +#define SFRT_SANDBOX_RUN_QUEUE_PS_H #include "sandbox.h" void sandbox_run_queue_ps_initialize(); -#endif /* SFRT_SANDBOX_RUN_QUEUE_FIFO_H */ \ No newline at end of file +#endif /* SFRT_SANDBOX_RUN_QUEUE_PS_H */ \ No newline at end of file diff --git a/runtime/src/priority_queue.c b/runtime/src/priority_queue.c index 7a36141..4c4ecee 100644 --- a/runtime/src/priority_queue.c +++ b/runtime/src/priority_queue.c @@ -82,12 +82,11 @@ priority_queue_find_smallest_child(struct priority_queue *self, int parent_index * @param self the priority queue */ static inline void -priority_queue_percolate_down(struct priority_queue *self) +priority_queue_percolate_down(struct priority_queue *self, int parent_index) { assert(self != NULL); assert(self->get_priority != NULL); - int parent_index = 1; int left_child_index = 2 * parent_index; while (left_child_index >= 2 && left_child_index < self->first_free) { int smallest_child_index = priority_queue_find_smallest_child(self, parent_index); @@ -173,6 +172,31 @@ priority_queue_enqueue(struct priority_queue *self, void *value) ck_spinlock_fas_unlock(&self->lock); return rc; } +/** + * @param self - the priority queue we want to delete from + * @param value - the value we want to delete + * @returns 0 on success. -1 on not found. -2 on unable to take lock + **/ +int +priority_queue_delete(struct priority_queue *self, void *value) +{ + assert(self != NULL); + if (ck_spinlock_fas_trylock(&self->lock) == false) return -2; + + bool did_delete = false; + for (int i = 1; i < self->first_free; i++) { + if (self->items[i] == value) { + self->items[i] = self->items[self->first_free - 1]; + self->items[self->first_free - 1] = NULL; + self->first_free--; + priority_queue_percolate_down(self, i); + did_delete = true; + } + } + ck_spinlock_fas_unlock(&self->lock); + if (!did_delete) return -1; + return 0; +} static bool priority_queue_is_empty(struct priority_queue *self) @@ -201,7 +225,7 @@ priority_queue_dequeue(struct priority_queue *self) self->items[self->first_free - 1] = NULL; self->first_free--; // Because of 1-based indices, first_free is 2 when there is only one element - if (self->first_free > 2) priority_queue_percolate_down(self); + if (self->first_free > 2) priority_queue_percolate_down(self, 1); // Update the highest priority self->highest_priority = !priority_queue_is_empty(self) ? self->get_priority(self->items[1]) @@ -211,3 +235,9 @@ priority_queue_dequeue(struct priority_queue *self) // End of Critical Section return min; } + +uint64_t +priority_queue_peek(struct priority_queue *self) +{ + return self->highest_priority; +} \ No newline at end of file diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c index bf95b39..d49c5d1 100644 --- a/runtime/src/runtime.c +++ b/runtime/src/runtime.c @@ -18,7 +18,7 @@ #include #include #include -// #include +#include #include #include #include diff --git a/runtime/src/sandbox_request_scheduler_ps.c b/runtime/src/sandbox_request_scheduler_ps.c index cd31120..82e2b41 100644 --- a/runtime/src/sandbox_request_scheduler_ps.c +++ b/runtime/src/sandbox_request_scheduler_ps.c @@ -27,7 +27,17 @@ sandbox_request_scheduler_ps_remove(void) return (sandbox_request_t *)priority_queue_dequeue(&sandbox_request_scheduler_ps); } -unsigned long long int +/** + * + * @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(void *element) { sandbox_request_t *sandbox_request = (sandbox_request_t *)element; @@ -46,7 +56,8 @@ sandbox_request_scheduler_ps_initialize() // Register Function Pointers for Abstract Scheduling API sandbox_request_scheduler_config_t config = { .add = sandbox_request_scheduler_ps_add, - .remove = sandbox_request_scheduler_ps_remove }; + .remove = sandbox_request_scheduler_ps_remove, + .peek = sandbox_request_scheduler_ps_peek }; sandbox_request_scheduler_initialize(&config); } \ No newline at end of file diff --git a/runtime/src/sandbox_run_queue.c b/runtime/src/sandbox_run_queue.c index 48bfd07..534125e 100644 --- a/runtime/src/sandbox_run_queue.c +++ b/runtime/src/sandbox_run_queue.c @@ -18,6 +18,13 @@ sandbox_run_queue_add(struct sandbox *sandbox) return sandbox_run_queue.add(sandbox); } +void +sandbox_run_queue_delete(struct sandbox *sandbox) +{ + assert(sandbox_run_queue.delete != NULL); + sandbox_run_queue.delete(sandbox); +} + // Removes a sandbox request struct sandbox * sandbox_run_queue_remove() diff --git a/runtime/src/sandbox_run_queue_fifo.c b/runtime/src/sandbox_run_queue_fifo.c index 223c13e..a8424f8 100644 --- a/runtime/src/sandbox_run_queue_fifo.c +++ b/runtime/src/sandbox_run_queue_fifo.c @@ -54,7 +54,8 @@ sandbox_run_queue_fifo_initialize() // 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 }; + .remove = sandbox_run_queue_fifo_remove_and_return, + .delete = sandbox_run_queue_fifo_remove }; sandbox_run_queue_initialize(&config); } \ No newline at end of file diff --git a/runtime/src/sandbox_run_queue_ps.c b/runtime/src/sandbox_run_queue_ps.c index ee20f2f..d9cd4c1 100644 --- a/runtime/src/sandbox_run_queue_ps.c +++ b/runtime/src/sandbox_run_queue_ps.c @@ -34,7 +34,19 @@ sandbox_run_queue_ps_remove(void) return (struct sandbox *)priority_queue_dequeue(&sandbox_run_queue_ps); } -unsigned long long int +/** + * + * @returns A Sandbox Request or NULL + **/ +static void +sandbox_run_queue_ps_delete(struct sandbox *sandbox) +{ + assert(sandbox != NULL); + int rc = priority_queue_delete(&sandbox_run_queue_ps, sandbox); + assert(rc != -2); +} + +uint64_t sandbox_get_priority(void *element) { struct sandbox *sandbox = (struct sandbox *)element; @@ -50,7 +62,8 @@ sandbox_run_queue_ps_initialize() // 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 }; + .remove = sandbox_run_queue_ps_remove, + .delete = sandbox_run_queue_ps_delete }; sandbox_run_queue_initialize(&config); } diff --git a/runtime/src/worker_thread.c b/runtime/src/worker_thread.c index 1aa2b47..917f77a 100644 --- a/runtime/src/worker_thread.c +++ b/runtime/src/worker_thread.c @@ -18,7 +18,7 @@ #include #include #include -// #include +#include #include #include #include @@ -102,7 +102,7 @@ worker_thread_block_current_sandbox(void) // Remove the sandbox we were just executing from the runqueue and mark as blocked struct sandbox *previous_sandbox = current_sandbox_get(); - sandbox_run_queue_remove(previous_sandbox); + sandbox_run_queue_delete(previous_sandbox); previous_sandbox->state = BLOCKED; // Switch to the next sandbox @@ -269,14 +269,14 @@ worker_thread_exit_current_sandbox(void) struct sandbox *previous_sandbox = current_sandbox_get(); assert(previous_sandbox); software_interrupt_disable(); - sandbox_run_queue_remove(previous_sandbox); + sandbox_run_queue_delete(previous_sandbox); previous_sandbox->state = RETURNED; struct sandbox *next_sandbox = worker_thread_get_next_sandbox(); assert(next_sandbox != previous_sandbox); software_interrupt_enable(); - // Because the stack is still in use, only unmap linear memory and defer free resources until "main function - // execution" + // Because the stack is still in use, only unmap linear memory and defer free resources until "main + // function execution" munmap(previous_sandbox->linear_memory_start, SBOX_MAX_MEM + PAGE_SIZE); worker_thread_switch_to_sandbox(next_sandbox); }