Reusable Barrier solution has a deadlock?

barrier, deadlock, reusability, semaphore

Solution

`mutex` protects the `count` variable. The first mutex lock is concerned with incrementing the counter to account for each thread, and the last thread to enter (`if count == n`) locks the second tunstile in preparation of leaving (see below) and releases the waiting (n-1) threads (that are waiting on line 10). Then each signals to the next.

The second mutex lock works similarly to the first, but decrements `count` (same mutext protects it). The last thread to enter the mutex block locks `turnstile` to prepare for the next batch entring (see above) and releases the (n-1) thread waiting on line 22. Then each thread signals to the next.

Thus `turnstile` coordinates the entries to the critical point, while `turnstile2` coordinates the exit from it.

There could be no deadlock: by the time the (last) thread gets to line 18, `turnstile` is guarantted to be not held by any other thread (they are all waiting on line 22). Similarly with `turnstile2`

Problem

I have been reading "The Little Book of Semaphores" and in page 41 there is a solution for the Reusable Barrier problem. The problem I have is why it won't generate a deadlock situation. ``` 1 # rendezvous 2 3 mutex.wait() 4 count += 1 5 if count == n: 6 turnstile2.wait() # lock the second 7 turnstile.signal() # unlock the first 8 mutex.signal() 9 10 turnstile.wait() # first turnstile 11 turnstile.signal() 12 13 # critical point 14 15 mutex.wait() 16 count -= 1 17 if count == 0: 18 turnstile.wait() # lock the first 19 turnstile2.signal() # unlock the second 20 mutex.signal() 21 22 turnstile2.wait() # second turnstile 23 turnstile2.signal() ``` In this solution, between lines 15 and 20, isn't it a bad habit to call wait() on a semaphore (in line 18) while holding a mutex which causes a deadlock? Please explain. Thank you.

Original source