Skip to content

Commit

Permalink
fix(threadpool): deadlock on Windows on fibonacci (#509)
Browse files Browse the repository at this point in the history
  • Loading branch information
mratsim authored Jan 7, 2025
1 parent 787e776 commit ea20f62
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions constantine/threadpool/crossthread/tasks_flowvars.nim
Original file line number Diff line number Diff line change
Expand Up @@ -142,16 +142,18 @@ proc isCompleted*(task: ptr Task): bool {.inline.} =
proc setCompleted*(task: ptr Task) {.inline.} =
## Set a task to `complete`
## Wake a waiter thread if there is one
task.state.completed.store(1, moRelease)
let waiter = task.state.synchro.load(moAcquire)
task.state.completed.store(1, moRelease) # Correctness on weak memory models like ARM: tests/t_ethereum_eip4844_deneb_kzg_parallel.nim
fence(moSequentiallyConsistent) # Avoid deadlock on Windows: benchmarks-threadpool/fibonacci/threadpool_fib.nim
let waiter = task.state.synchro.load(moRelaxed)
if (waiter and kWaiterMask) != SentinelWaiter:
task.state.completed.wake()

proc sleepUntilComplete*(task: ptr Task, waiterID: int32) {.inline.} =
## Sleep while waiting for task completion
let waiter = (cast[uint32](waiterID) shl kWaiterShift) - SentinelWaiter
discard task.state.synchro.fetchAdd(waiter, moRelease)
while task.state.completed.load(moAcquire) == 0:
discard task.state.synchro.fetchAdd(waiter, moRelaxed)
fence(moAcquire)
while task.state.completed.load(moRelaxed) == 0:
task.state.completed.wait(0)

# Leapfrogging synchronization
Expand Down

0 comments on commit ea20f62

Please sign in to comment.