5

I'm looking into the Reusable Barrier algorithm from the book "The Little Book Of Semaphores" (archived here).

The puzzle is on page 31 (Basic Synchronization Patterns/Reusable Barrier), and I have come up with a 'solution' (or not) which differs from the solution from the book (a two-phase barrier).

This is my 'code' for each thread:

# n = 4; threads running
# semaphore = n max., initialized to 0
# mutex, unowned.

start:
    mutex.wait()
        counter = counter + 1
        if counter = n:
            semaphore.signal(4) # add 4 at once
            counter = 0
    mutex.release()
    semaphore.wait()
        # critical section
    semaphore.release()
goto start

This does seem to work, I've even inserted different sleep timers into different sections of the threads, and they still wait for all the threads to come before continuing each and every loop. Am I missing something? Is there a condition that this will fail?

I've implemented this using the Windows library Semaphore and Mutex functions.

Update:

Thank you to starblue for the answer. Turns out that if for whatever reason a thread is slow between mutex.release() and semaphore.wait() any of the threads that arrive to semaphore.wait() after a full loop will be able to go through again, since there will be one of the N unused signals left.

And having put a Sleep command for thread number 3, I got this result where one can see that thread 3 missed a turn the first time, with thread 1 having done 2 turns, and then catching up on the second turn (which was in fact its 1st turn).

Thanks again to everyone for the input.

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
soulseekah
  • 8,770
  • 3
  • 53
  • 58
  • the book link is broken, archived here: https://web.archive.org/web/20160310235613/http://greenteapress.com/semaphores/downey08semaphores.pdf – Claude May 07 '17 at 16:55
  • 1
    Book was moved here: http://greenteapress.com/semaphores/LittleBookOfSemaphores.pdf – soulseekah May 08 '17 at 20:44

1 Answers1

4

One thread could run several times through the barrier while some other thread doesn't run at all.

starblue
  • 55,348
  • 14
  • 97
  • 151
  • Actually, it won't run several times. There is a counter. Only when one of the threads find it is set to N (all threads are waiting) that it signals the semaphore (N), so that they can all go through. The counter is set to 0 again, so the barrier is locked. They all go through only when all are waiting. – soulseekah Feb 19 '11 at 09:39
  • So one thread could not run several times, because one thread increments the counter by 1, only once. And resets the counter to 0 when it finds the counter is equal to N (all threads including itself incremented the counter). One thread never goes alone. The semaphore will hold it locked, until all of them arrive, then they go. It will never be able to complete a loop while it's waiting/locked. – soulseekah Feb 19 '11 at 09:41
  • If the others don't go through the semaphore then one thread can go through N times. The counter doesn't matter as long as the semaphore is open. – starblue Feb 19 '11 at 10:30
  • Where would the others be? Stuck inside the mutex? Then none can get inside the mutex, they get back up to the beginning of the loop, but won't be able to get inside; it's a deadlock; if one thread is stuck somewhere, everyone is stuck, at either a mutex or a semaphore. Still trying to get my head around this. Thank you for your input. – soulseekah Feb 19 '11 at 11:35
  • 1
    No, they would be after the mutex but before the semaphore. They aren't blocked after `semaphore.signal(4)` is executed, they just don't run for no particular reason. – starblue Feb 19 '11 at 12:47
  • OK. Tried to stop the threads between `mutex.release()` and `semaphore.wait()`, all is fine, everything stops at the next `semaphore.wait()` before the critical section, they are all waiting for the barrier to open, so no thread can keep on looping by itself. – soulseekah Feb 19 '11 at 15:14
  • I take my comment above back. Actually, you are right. http://pastebin.com/raw.php?i=FfXcCMZ3 you can see that thread 3 (in the 2nd loop) went to sleep, and never went through the barrier, while thread 1 got to go through twice since 4 signals were available to whichever thread. That is NOT in sync. Thank you so much for your input! – soulseekah Feb 19 '11 at 15:25