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

Reply via email to