So I am trying to introduce dependencies between threads, but my program deadlocks. It seems that the first thread is never spawned. I appreciate any feedback.
import std/random, malebolgia, sync/semaphore
const
numElements = 16384
bulkSize = 256
numBlocks = numElements div bulkSize
var semaphores: array[numBlocks, Semaphore]
var data: array[numElements, int32]
type
SubmitInfo = object
waitSemaphore: ptr Semaphore
signalSemaphore: ptr Semaphore
template `@!`[T](data: openArray[T]; i: int): untyped =
cast[ptr UncheckedArray[T]](addr data[i])
proc worker[Tin, Tout](info: ptr SubmitInfo; a: ptr UncheckedArray[Tin];
dest: ptr UncheckedArray[Tout]; until: int) =
if info.waitSemaphore != nil:
wait(info.waitSemaphore[])
for i in 1..<until:
dest[i] = a[i-1] + a[i]
signal(info.signalSemaphore[])
proc main =
for i in 0 ..< numElements:
data[i] = rand(0..4).int32
# Create semaphores for each block.
for i in 0 ..< numBlocks:
init(semaphores[i])
var m = createMaster()
var result = newSeq[int32](numElements)
m.awaitAll:
# Submit each block's work with the necessary semaphores.
var s = 0
for i in 0 ..< numBlocks:
let submitInfo = SubmitInfo(
waitSemaphore: if i == 0: nil else: semaphores[i - 1].addr,
signalSemaphore: semaphores[i].addr
)
m.spawn worker(submitInfo.addr, data@!s, result@!s, bulkSize)
s += bulkSize
echo result
main()
ThreadSanitizer complains:
/usr/bin/llvm-symbolizer: error: '[stack]': No such file or directory
==================
WARNING: ThreadSanitizer: data race (pid=45323)
Read of size 8 at 0x7ffde10eb590 by thread T1:
#0 worker::worker(ptr<psum_naive::SubmitInfo>, ptr<uncheckedArray<int32>>, ptr<uncheckedArray<int32>>, int) wparallel/paralgos/psum_naive.nim:21:24 (psum_naive+0xfdd48) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#1 main::worker(pointer, pointer) /home/antonisg/Build/Nim/lib/std/tasks.nim:220:2 (psum_naive+0xfdd48)
#2 tasks::invoke(tasks::Task, pointer) /home/antonisg/Build/Nim/lib/std/tasks.nim:90:2 (psum_naive+0xfcafe) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#3 malebolgia::worker wparallel/malebolgia/src/malebolgia.nim:143:5 (psum_naive+0xfcafe)
#4 threadProcWrapDispatch::threadProcWrapDispatch(ptr<Thread<void>>) /home/antonisg/Build/Nim/lib/system/threadimpl.nim:66:2 (psum_naive+0xfb033) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#5 threadProcWrapStackFrame::threadProcWrapStackFrame(ptr<Thread<void>>) /home/antonisg/Build/Nim/lib/system/threadimpl.nim:95:2 (psum_naive+0xfb033)
#6 threadProcWrapper::threadProcWrapper(pointer) /home/antonisg/Build/Nim/lib/system/threadimpl.nim:101:2 (psum_naive+0xf7b73) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
Previous write of size 8 at 0x7ffde10eb590 by main thread:
#0 psum_naive::main wparallel/paralgos/psum_naive.nim (psum_naive+0xfdfbc) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#1 NimMainModule wparallel/paralgos/psum_naive.nim:48:2 (psum_naive+0xfe575) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#2 NimMainInner wparallel/paralgos/psum_naive.nim:32:2 (psum_naive+0xfe69c) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#3 NimMain wparallel/paralgos/psum_naive.nim:43:2 (psum_naive+0xfe69c)
#4 main wparallel/paralgos/psum_naive.nim:51:2 (psum_naive+0xfe69c)
Location is stack of main thread.
Location is global '??' at 0x7ffde10cc000 ([stack]+0x1f590)
Thread T1 (tid=45325, running) created by main thread at:
#0 pthread_create <null> (psum_naive+0x74776) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#1 createThread::createThread(var<Thread<void>>, proc<>) /home/antonisg/Build/Nim/lib/std/typedthreads.nim:286:106 (psum_naive+0xf7c55) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#2 malebolgia::setup wparallel/malebolgia/src/malebolgia.nim:160:99 (psum_naive+0xfcf3d) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#3 atmdotdotatsmalebolgiaatssrcatsmalebolgiadotnim_Init000 wparallel/malebolgia/src/malebolgia.nim:257:2 (psum_naive+0xfda0f) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#4 PreMainInner wparallel/paralgos/psum_naive.nim:15:2 (psum_naive+0xfe697) (BuildId: 11e963ea9b1375efc8e610c80a134545cb0a13c6)
#5 PreMain wparallel/paralgos/psum_naive.nim:27:2 (psum_naive+0xfe697)
#6 NimMain wparallel/paralgos/psum_naive.nim:42:2 (psum_naive+0xfe697)
#7 main wparallel/paralgos/psum_naive.nim:51:2 (psum_naive+0xfe697)
SUMMARY: ThreadSanitizer: data race wparallel/paralgos/psum_naive.nim:21:24 in worker::worker(ptr<psum_naive::SubmitInfo>, ptr<uncheckedArray<int32>>, ptr<uncheckedArray<int32>>, int)
==================