refactor: simplify worker checking logic

main
Sean McBride 4 years ago
parent f38b08cee7
commit 176d67ac90

@ -1,10 +1,24 @@
#pragma once #pragma once
#include <stdbool.h>
#include "generic_thread.h" #include "generic_thread.h"
#include "module.h" #include "module.h"
#define LISTENER_THREAD_CORE_ID 0 #define LISTENER_THREAD_CORE_ID 0
extern pthread_t listener_thread_id;
void listener_thread_initialize(void); void listener_thread_initialize(void);
__attribute__((noreturn)) void *listener_thread_main(void *dummy); __attribute__((noreturn)) void *listener_thread_main(void *dummy);
int listener_thread_register_module(struct module *mod); 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;
}

@ -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 * @param unique_variable_name - a unique prefix to hygienically namespace an associated lock/unlock pair
*/ */
#define LOCK_LOCK_WITH_BOOKKEEPING(lock, unique_variable_name) \ #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; \ struct ck_spinlock_mcs _hygiene_##unique_variable_name##_node; \
uint64_t _hygiene_##unique_variable_name##_pre = __getcycles(); \ uint64_t _hygiene_##unique_variable_name##_pre = __getcycles(); \
ck_spinlock_mcs_lock((lock), &(_hygiene_##unique_variable_name##_node)); \ 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 lock - the address of the lock
* @param unique_variable_name - a unique prefix to hygienically namespace an associated lock/unlock pair * @param unique_variable_name - a unique prefix to hygienically namespace an associated lock/unlock pair
*/ */
#define LOCK_UNLOCK_WITH_BOOKKEEPING(lock, unique_variable_name) \ #define LOCK_UNLOCK_WITH_BOOKKEEPING(lock, unique_variable_name) \
assert(!runtime_is_worker() || !software_interrupt_is_enabled()); \ assert(listener_thread_is_running() || !software_interrupt_is_enabled()); \
ck_spinlock_mcs_unlock(lock, &(_hygiene_##unique_variable_name##_node)); ck_spinlock_mcs_unlock(lock, &(_hygiene_##unique_variable_name##_node));
/** /**

@ -71,21 +71,6 @@ extern void runtime_initialize(void);
extern void runtime_set_resource_limits_to_max(); extern void runtime_set_resource_limits_to_max();
extern void stub_init(int32_t offset); 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 * static inline char *
runtime_print_scheduler(enum RUNTIME_SCHEDULER variant) runtime_print_scheduler(enum RUNTIME_SCHEDULER variant)
{ {

@ -1,6 +1,7 @@
#include <assert.h> #include <assert.h>
#include "global_request_scheduler.h" #include "global_request_scheduler.h"
#include "listener_thread.h"
#include "panic.h" #include "panic.h"
#include "priority_queue.h" #include "priority_queue.h"
#include "runtime.h" #include "runtime.h"
@ -17,7 +18,7 @@ global_request_scheduler_minheap_add(void *sandbox_request)
{ {
assert(sandbox_request); assert(sandbox_request);
assert(global_request_scheduler_minheap); 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); int return_code = priority_queue_enqueue(global_request_scheduler_minheap, sandbox_request);
/* TODO: Propagate -1 to caller. Issue #91 */ /* TODO: Propagate -1 to caller. Issue #91 */

@ -17,6 +17,8 @@ int listener_thread_epoll_file_descriptor;
/* Timestamp when listener thread began executing */ /* Timestamp when listener thread began executing */
static __thread uint64_t listener_thread_start_timestamp; 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 * 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); listener_thread_epoll_file_descriptor = epoll_create1(0);
assert(listener_thread_epoll_file_descriptor >= 0); assert(listener_thread_epoll_file_descriptor >= 0);
pthread_t listener_thread; int ret = pthread_create(&listener_thread_id, NULL, listener_thread_main, NULL);
int ret = pthread_create(&listener_thread, NULL, listener_thread_main, NULL);
assert(ret == 0); 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); assert(ret == 0);
ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs); ret = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs);
assert(ret == 0); assert(ret == 0);
printf("\tListener core thread: %lx\n", listener_thread); printf("\tListener core thread: %lx\n", listener_thread_id);
} }
/** /**

@ -5,6 +5,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "listener_thread.h"
#include "panic.h" #include "panic.h"
#include "priority_queue.h" #include "priority_queue.h"
@ -55,7 +56,7 @@ priority_queue_is_empty(struct priority_queue *self)
{ {
assert(self != NULL); assert(self != NULL);
assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); 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; return self->size == 0;
} }
@ -133,7 +134,7 @@ priority_queue_percolate_down(struct priority_queue *self, int parent_index)
assert(self != NULL); assert(self != NULL);
assert(self->get_priority_fn != NULL); assert(self->get_priority_fn != NULL);
assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock));
assert(runtime_is_worker()); assert(!listener_thread_is_running());
assert(!software_interrupt_is_enabled()); assert(!software_interrupt_is_enabled());
bool update_highest_value = parent_index == 1; 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) priority_queue_initialize(size_t capacity, bool use_lock, priority_queue_get_priority_fn_t get_priority_fn)
{ {
assert(get_priority_fn != NULL); 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 */ /* Add one to capacity because this data structure ignores the element at 0 */
size_t one_based_capacity = capacity + 1; size_t one_based_capacity = capacity + 1;
@ -207,7 +208,7 @@ void
priority_queue_free(struct priority_queue *self) priority_queue_free(struct priority_queue *self)
{ {
assert(self != NULL); assert(self != NULL);
assert(!runtime_is_worker() || !software_interrupt_is_enabled()); assert(listener_thread_is_running() || !software_interrupt_is_enabled());
free(self); free(self);
} }
@ -220,7 +221,7 @@ int
priority_queue_length_nolock(struct priority_queue *self) priority_queue_length_nolock(struct priority_queue *self)
{ {
assert(self != NULL); assert(self != NULL);
assert(runtime_is_worker()); assert(!listener_thread_is_running());
assert(!software_interrupt_is_enabled()); assert(!software_interrupt_is_enabled());
assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); 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(self != NULL);
assert(value != 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)); assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock));
int rc; int rc;
@ -294,7 +295,7 @@ priority_queue_delete_nolock(struct priority_queue *self, void *value)
{ {
assert(self != NULL); assert(self != NULL);
assert(value != NULL); assert(value != NULL);
assert(runtime_is_worker()); assert(!listener_thread_is_running());
assert(!software_interrupt_is_enabled()); assert(!software_interrupt_is_enabled());
assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); 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(self != NULL);
assert(dequeued_element != NULL); assert(dequeued_element != NULL);
assert(self->get_priority_fn != NULL); assert(self->get_priority_fn != NULL);
assert(runtime_is_worker()); assert(!listener_thread_is_running());
assert(!software_interrupt_is_enabled()); assert(!software_interrupt_is_enabled());
assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); 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(self != NULL);
assert(dequeued_element != NULL); assert(dequeued_element != NULL);
assert(self->get_priority_fn != NULL); assert(self->get_priority_fn != NULL);
assert(runtime_is_worker()); assert(!listener_thread_is_running());
assert(!software_interrupt_is_enabled()); assert(!software_interrupt_is_enabled());
assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock)); assert(!self->use_lock || LOCK_IS_LOCKED(&self->lock));

@ -11,6 +11,7 @@
#include "current_sandbox.h" #include "current_sandbox.h"
#include "debuglog.h" #include "debuglog.h"
#include "global_request_scheduler.h" #include "global_request_scheduler.h"
#include "listener_thread.h"
#include "local_runqueue.h" #include "local_runqueue.h"
#include "module.h" #include "module.h"
#include "panic.h" #include "panic.h"
@ -169,7 +170,7 @@ static inline void
software_interrupt_validate_worker() software_interrupt_validate_worker()
{ {
#ifndef NDEBUG #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 #endif
} }

Loading…
Cancel
Save