I think the problem was that when the main thread enetered the signal loop, no 
thread had actually started executing yet so thaht when the signal was called 
there were no threads waiting on the Cond, I added a sleep(1000) between the 
createThread loop and the signal loop and the code seems to work.
    
    
    import locks
    import cpuinfo
    import strutils
    import os
    
    
    var
      thr = newSeq[Thread[int]](countProcessors())
      lock: Lock
      cond : Cond
    
    var counter = 0
    proc threadFunc(i: int) {.thread.} =
        counter += 1
        withLock(lock):
            cond.wait(lock)
            counter -= 1
            echo "$# $#" % [$i, $counter]
    
    initLock(lock)
    initCond(cond)
    
    withLock(lock):
        for i in 0..<thr.len:
            createThread(thr[i], threadFunc, i)
    
    sleep(1000)
    
    for i in 0..<thr.len:
        cond.signal()
    
    for i in 0..<thr.len:
        joinThreads(thr)
    

> More likely, One thread will win the lock from that signal() loop, and the 
> rest will go back to sleep. After that initial loop, there is no mechanism to 
> wake the threads up again

Do you mean that it is possible that I call signal from the main thread with, 
say, two threads waiting on a Cond, then I call signal again from the main 
thread on the same cond, if the scheduler does not context switch to one of the 
two waiting thread between the two calls just one thread is woken up and the 
second one remains waiting? 

Reply via email to