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()
Run