Skip to content

Commit

Permalink
handle data-race on nrunning==0 from scheduler_delete_thread
Browse files Browse the repository at this point in the history
Could be observed by thread 0 during certain phases, since if the dying
thread was not running, it was not supposed to call jl_wakeup_thread
(which will not increment nrunning until after the wakeup).
  • Loading branch information
vtjnash committed Dec 12, 2023
1 parent e0568e2 commit a1ef2f3
Showing 1 changed file with 8 additions and 4 deletions.
12 changes: 8 additions & 4 deletions src/scheduler.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,9 +581,10 @@ JL_DLLEXPORT jl_task_t *jl_task_get_next(jl_value_t *trypoptask, jl_value_t *q,

void scheduler_delete_thread(jl_ptls_t ptls) JL_NOTSAFEPOINT
{
if (jl_atomic_exchange_relaxed(&ptls->sleep_check_state, sleeping_like_the_dead) != sleeping) {
int wasrunning = jl_atomic_fetch_add_relaxed(&nrunning, -1);
if (wasrunning == 1) {
int notsleeping = jl_atomic_exchange_relaxed(&ptls->sleep_check_state, sleeping_like_the_dead) == not_sleeping;
jl_fence();
if (notsleeping) {
if (jl_atomic_load_relaxed(&nrunning) == 1) {
jl_ptls_t ptls2 = jl_atomic_load_relaxed(&jl_all_tls_states)[0];
// This was the last running thread, and there is no thread with !may_sleep
// so make sure tid 0 is notified to check wait_empty
Expand All @@ -592,8 +593,11 @@ void scheduler_delete_thread(jl_ptls_t ptls) JL_NOTSAFEPOINT
uv_mutex_unlock(&ptls2->sleep_lock);
}
}
jl_fence();
else {
jl_atomic_fetch_add_relaxed(&nrunning, 1);
}
jl_wakeup_thread(0); // force thread 0 to see that we do not have the IO lock (and am dead)
jl_atomic_fetch_add_relaxed(&nrunning, -1);
}

#ifdef __cplusplus
Expand Down

0 comments on commit a1ef2f3

Please sign in to comment.