From ab1dda237fdabfd0fd38eb6c51ce219e5e15c1f4 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Wed, 13 Dec 2023 16:24:09 +0000 Subject: [PATCH] add missing increment of nrunning for jl_adopt_thread --- src/scheduler.c | 16 +++++++++++++++- src/threading.c | 5 ++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/scheduler.c b/src/scheduler.c index d0517c7e4afc9..50e15b286a8eb 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -32,7 +32,7 @@ static const int16_t sleeping_like_the_dead JL_UNUSED = 2; // a running count of how many threads are currently not_sleeping // plus a running count of the number of in-flight wake-ups // n.b. this may temporarily exceed jl_n_threads -static _Atomic(int) nrunning = 1; +static _Atomic(int) nrunning = 0; // invariant: No thread is ever asleep unless sleep_check_state is sleeping (or we have a wakeup signal pending). // invariant: Any particular thread is not asleep unless that thread's sleep_check_state is sleeping. @@ -201,6 +201,20 @@ void jl_threadfun(void *arg) } + +void jl_init_thread_scheduler(jl_ptls_t ptls) JL_NOTSAFEPOINT +{ + uv_mutex_init(&ptls->sleep_lock); + uv_cond_init(&ptls->wake_signal); + // record that there is now another thread that may be used to schedule work + // we will decrement this again in scheduler_delete_thread, only slightly + // in advance of pthread_join (which hopefully itself also had been + // adopted by now and is included in nrunning too) + (void)jl_atomic_fetch_add_relaxed(&nrunning, 1); + // n.b. this is the only point in the code where we ignore the invariants on the ordering of nrunning + // since we are being initialized from foreign code, we could not necessarily have expected or predicted that to happen +} + int jl_running_under_rr(int recheck) { #ifdef _OS_LINUX_ diff --git a/src/threading.c b/src/threading.c index f0ee5cca363ea..648f7d935bac2 100644 --- a/src/threading.c +++ b/src/threading.c @@ -316,6 +316,7 @@ int jl_all_tls_states_size; static uv_cond_t cond; // concurrent reads are permitted, using the same pattern as mtsmall_arraylist // it is implemented separately because the API of direct jl_all_tls_states use is already widely prevalent +void jl_init_thread_scheduler(jl_ptls_t ptls) JL_NOTSAFEPOINT; // return calling thread's ID JL_DLLEXPORT int16_t jl_threadid(void) @@ -379,9 +380,7 @@ jl_ptls_t jl_init_threadtls(int16_t tid) ptls->bt_data = bt_data; small_arraylist_new(&ptls->locks, 0); jl_init_thread_heap(ptls); - - uv_mutex_init(&ptls->sleep_lock); - uv_cond_init(&ptls->wake_signal); + jl_init_thread_scheduler(ptls); uv_mutex_lock(&tls_lock); if (tid == -1)