Skip to content

Commit

Permalink
fix freeze on @threads loop exit (#45899)
Browse files Browse the repository at this point in the history
Closes #45626, hopefully.

(cherry picked from commit f7e0c7e)
  • Loading branch information
vtjnash authored and KristofferC committed Jul 8, 2022
1 parent e3c2c25 commit c118103
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/jl_uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void JL_UV_LOCK(void)
}
else {
jl_atomic_fetch_add_relaxed(&jl_uv_n_waiters, 1);
jl_fence(); // [^store_buffering_2]
jl_wake_libuv();
JL_LOCK(&jl_uv_mutex);
jl_atomic_fetch_add_relaxed(&jl_uv_n_waiters, -1);
Expand Down
11 changes: 9 additions & 2 deletions src/partr.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,14 @@ static const int16_t sleeping = 1;
// * 2a: `multiq_insert`
// * 2b: `jl_atomic_load_relaxed(&ptls->sleep_check_state)` in `jl_wakeup_thread` returns `not_sleeping`
// i.e., the dequeuer misses the enqueue and enqueuer misses the sleep state transition.

// [^store_buffering_2]: and also
// * Enqueuer:
// * 1a: `jl_atomic_store_relaxed(jl_uv_n_waiters, 1)` in `JL_UV_LOCK`
// * 1b: "cheap read" of `handle->pending` in `uv_async_send` (via `JL_UV_LOCK`) loads `0`
// * Dequeuer:
// * 2a: store `2` to `handle->pending` in `uv_async_send` (via `JL_UV_LOCK` in `jl_task_get_next`)
// * 2b: `jl_atomic_load_relaxed(jl_uv_n_waiters)` in `jl_task_get_next` returns `0`
// i.e., the dequeuer misses the `n_waiters` is set and enqueuer misses the `uv_stop` flag (in `signal_async`) transition to cleared

JULIA_DEBUG_SLEEPWAKE(
uint64_t wakeup_enter;
Expand Down Expand Up @@ -462,7 +469,7 @@ static int may_sleep(jl_ptls_t ptls) JL_NOTSAFEPOINT
// by the thread itself. As a result, if this returns false, it will
// continue returning false. If it returns true, we know the total
// modification order of the fences.
jl_fence(); // [^store_buffering_1]
jl_fence(); // [^store_buffering_1] [^store_buffering_2]
return jl_atomic_load_relaxed(&ptls->sleep_check_state) == sleeping;
}

Expand Down

0 comments on commit c118103

Please sign in to comment.