From 176d67ac9049d767238cc932eb7697151b93a6a9 Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Wed, 5 May 2021 08:40:22 -0400 Subject: [PATCH] refactor: simplify worker checking logic --- runtime/include/listener_thread.h | 14 ++++++++++++++ runtime/include/lock.h | 6 +++--- runtime/include/runtime.h | 15 --------------- .../src/global_request_scheduler_minheap.c | 3 ++- runtime/src/listener_thread.c | 9 +++++---- runtime/src/priority_queue.c | 19 ++++++++++--------- runtime/src/software_interrupt.c | 3 ++- 7 files changed, 36 insertions(+), 33 deletions(-) diff --git a/runtime/include/listener_thread.h b/runtime/include/listener_thread.h index 26d5962..a00a4f4 100644 --- a/runtime/include/listener_thread.h +++ b/runtime/include/listener_thread.h @@ -1,10 +1,24 @@ #pragma once +#include + #include "generic_thread.h" #include "module.h" #define LISTENER_THREAD_CORE_ID 0 +extern pthread_t listener_thread_id; + void listener_thread_initialize(void); __attribute__((noreturn)) void *listener_thread_main(void *dummy); int listener_thread_register_module(struct module *mod); + +/** + * Used to determine if running in the context of a listener thread + * @returns true if listener. false if not (probably a worker) + */ +static inline bool +listener_thread_is_running() +{ + return pthread_self() == listener_thread_id; +} diff --git a/runtime/include/lock.h b/runtime/include/lock.h index d21677a..608d924 100644 --- a/runtime/include/lock.h +++ b/runtime/include/lock.h @@ -28,7 +28,7 @@ typedef ck_spinlock_mcs_t lock_t; * @param unique_variable_name - a unique prefix to hygienically namespace an associated lock/unlock pair */ #define LOCK_LOCK_WITH_BOOKKEEPING(lock, unique_variable_name) \ - assert(!runtime_is_worker() || !software_interrupt_is_enabled()); \ + assert(listener_thread_is_running() || !software_interrupt_is_enabled()); \ struct ck_spinlock_mcs _hygiene_##unique_variable_name##_node; \ uint64_t _hygiene_##unique_variable_name##_pre = __getcycles(); \ ck_spinlock_mcs_lock((lock), &(_hygiene_##unique_variable_name##_node)); \ @@ -39,8 +39,8 @@ typedef ck_spinlock_mcs_t lock_t; * @param lock - the address of the lock * @param unique_variable_name - a unique prefix to hygienically namespace an associated lock/unlock pair */ -#define LOCK_UNLOCK_WITH_BOOKKEEPING(lock, unique_variable_name) \ - assert(!runtime_is_worker() || !software_interrupt_is_enabled()); \ +#define LOCK_UNLOCK_WITH_BOOKKEEPING(lock, unique_variable_name) \ + assert(listener_thread_is_running() || !software_interrupt_is_enabled()); \ ck_spinlock_mcs_unlock(lock, &(_hygiene_##unique_variable_name##_node)); /** diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h index 4253faa..81cfbd2 100644 --- a/runtime/include/runtime.h +++ b/runtime/include/runtime.h @@ -71,21 +71,6 @@ extern void runtime_initialize(void); extern void runtime_set_resource_limits_to_max(); extern void stub_init(int32_t offset); -/** - * Used to determine if running in the context of a worker thread - * @returns true if worker. false if listener core - */ -static inline bool -runtime_is_worker() -{ - pthread_t self = pthread_self(); - for (int i = 0; i < runtime_worker_threads_count; i++) { - if (runtime_worker_threads[i] == self) return true; - } - - return false; -} - static inline char * runtime_print_scheduler(enum RUNTIME_SCHEDULER variant) { diff --git a/runtime/src/global_request_scheduler_minheap.c b/runtime/src/global_request_scheduler_minheap.c index c6ddd2d..d5759cc 100644 --- a/runtime/src/global_request_scheduler_minheap.c +++ b/runtime/src/global_request_scheduler_minheap.c @@ -1,6 +1,7 @@ #include #include "global_request_scheduler.h" +#include "listener_thread.h" #include "panic.h" #include "priority_queue.h" #include "runtime.h" @@ -17,7 +18,7 @@ global_request_scheduler_minheap_add(void *sandbox_request) { assert(sandbox_request); assert(global_request_scheduler_minheap); - if (unlikely(runtime_is_worker())) panic("%s is only callable by the listener thread\n", __func__); + if (unlikely(!listener_thread_is_running())) panic("%s is only callable by the listener thread\n", __func__); int return_code = priority_queue_enqueue(global_request_scheduler_minheap, sandbox_request); /* TODO: Propagate -1 to caller. Issue #91 */ diff --git a/runtime/src/listener_thread.c b/runtime/src/listener_thread.c index 450ec4d..fff839c 100644 --- a/runtime/src/listener_thread.c +++ b/runtime/src/listener_thread.c @@ -17,6 +17,8 @@ int listener_thread_epoll_file_descriptor; /* Timestamp when listener thread began executing */ static __thread uint64_t listener_thread_start_timestamp; +pthread_t listener_thread_id; + /** * Initializes the listener thread, pinned to core 0, and starts to listen for requests */ @@ -33,15 +35,14 @@ listener_thread_initialize(void) listener_thread_epoll_file_descriptor = epoll_create1(0); assert(listener_thread_epoll_file_descriptor >= 0); - pthread_t listener_thread; - int ret = pthread_create(&listener_thread, NULL, listener_thread_main, NULL); + int ret = pthread_create(&listener_thread_id, NULL, listener_thread_main, NULL); assert(ret == 0); - ret = pthread_setaffinity_np(listener_thread, sizeof(cpu_set_t), &cs); + ret = pthread_setaffinity_np(listener_thread_id, sizeof(cpu_set_t), &cs); assert(ret == 0); ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs); assert(ret == 0); - printf("\tListener core thread: %lx\n", listener_thread); + printf("\tListener core thread: %lx\n", listener_thread_id); } /** diff --git a/runtime/src/priority_queue.c b/runtime/src/priority_queue.c index 6d057c9..fb76c75 100644 --- a/runtime/src/priority_queue.c +++ b/runtime/src/priority_queue.c @@ -5,6 +5,7 @@ #include #include +#include "listener_thread.h" #include "panic.h" #include "priority_queue.h" @@ -55,7 +56,7 @@ priority_queue_is_empty(struct priority_queue *self) { assert(self != NULL); assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); - assert(!runtime_is_worker() || !software_interrupt_is_enabled()); + assert(listener_thread_is_running() || !software_interrupt_is_enabled()); return self->size == 0; } @@ -133,7 +134,7 @@ priority_queue_percolate_down(struct priority_queue *self, int parent_index) assert(self != NULL); assert(self->get_priority_fn != NULL); assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); - assert(runtime_is_worker()); + assert(!listener_thread_is_running()); assert(!software_interrupt_is_enabled()); bool update_highest_value = parent_index == 1; @@ -179,7 +180,7 @@ struct priority_queue * priority_queue_initialize(size_t capacity, bool use_lock, priority_queue_get_priority_fn_t get_priority_fn) { assert(get_priority_fn != NULL); - assert(!runtime_is_worker() || !software_interrupt_is_enabled()); + assert(!software_interrupt_is_enabled()); /* Add one to capacity because this data structure ignores the element at 0 */ size_t one_based_capacity = capacity + 1; @@ -207,7 +208,7 @@ void priority_queue_free(struct priority_queue *self) { assert(self != NULL); - assert(!runtime_is_worker() || !software_interrupt_is_enabled()); + assert(listener_thread_is_running() || !software_interrupt_is_enabled()); free(self); } @@ -220,7 +221,7 @@ int priority_queue_length_nolock(struct priority_queue *self) { assert(self != NULL); - assert(runtime_is_worker()); + assert(!listener_thread_is_running()); assert(!software_interrupt_is_enabled()); assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); @@ -250,7 +251,7 @@ priority_queue_enqueue_nolock(struct priority_queue *self, void *value) { assert(self != NULL); assert(value != NULL); - assert(!runtime_is_worker() || !software_interrupt_is_enabled()); + assert(listener_thread_is_running() || !software_interrupt_is_enabled()); assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); int rc; @@ -294,7 +295,7 @@ priority_queue_delete_nolock(struct priority_queue *self, void *value) { assert(self != NULL); assert(value != NULL); - assert(runtime_is_worker()); + assert(!listener_thread_is_running()); assert(!software_interrupt_is_enabled()); assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); @@ -361,7 +362,7 @@ priority_queue_dequeue_if_earlier_nolock(struct priority_queue *self, void **deq assert(self != NULL); assert(dequeued_element != NULL); assert(self->get_priority_fn != NULL); - assert(runtime_is_worker()); + assert(!listener_thread_is_running()); assert(!software_interrupt_is_enabled()); assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); @@ -414,7 +415,7 @@ priority_queue_top_nolock(struct priority_queue *self, void **dequeued_element) assert(self != NULL); assert(dequeued_element != NULL); assert(self->get_priority_fn != NULL); - assert(runtime_is_worker()); + assert(!listener_thread_is_running()); assert(!software_interrupt_is_enabled()); assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); diff --git a/runtime/src/software_interrupt.c b/runtime/src/software_interrupt.c index 8c66dae..fe45d1e 100644 --- a/runtime/src/software_interrupt.c +++ b/runtime/src/software_interrupt.c @@ -11,6 +11,7 @@ #include "current_sandbox.h" #include "debuglog.h" #include "global_request_scheduler.h" +#include "listener_thread.h" #include "local_runqueue.h" #include "module.h" #include "panic.h" @@ -169,7 +170,7 @@ static inline void software_interrupt_validate_worker() { #ifndef NDEBUG - if (!runtime_is_worker()) panic("A non-worker thread has unexpectedly received a signal!"); + if (listener_thread_is_running()) panic("The listener thread unexpectedly received a signal!"); #endif }