On 5 May 2014 at 20:56, Peter Dimov wrote:
Firstly, permits are a notification object, not a serialisation object. If you have some predicate P whose state you are changing you must protect it with a mutex, just like any other code. This is why permit.wait() takes a locked mutex.
But you do have a wait() function that takes nothing?
That wait never sleeps, so wakeups cannot be lost. There is actually an internal facility for sleeping waits without a mutex, but it is deliberately not documented as you shouldn't use it (it's only there because it made the Windows implementation much more efficient).
Reworking your example thusly:
Initially P is 0 and p_mutex is unlocked.
Tc1, Tc2 lock p_mutex and call wait.
Tp1 locks p_mutex, sets P=1 and calls notify_one. Upon Tp1 releasing the mutex, Tc1 is unblocked with mutex locked, returns from wait, but is immediately suspended by the scheduler for unfathomable scheduling reasons, like its code causing a page fault.
Tp2 tries to set P=1, but gets blocked on the mutex being held by Tc1. When Tc1 is resumed and eventually unlocks the mutex, everything else proceeds as normal.
This assumes that notify_one is called before releasing the mutex. Condition variables allow notify_one outside the mutex. Is this use not supported by permits?
Consuming permits let you grant either with or without the mutex. Non-consuming permits will deadlock if you grant holding the mutex because of the guarantee of blocking until the release of all current waiters. If you grant outside of the mutex, you accept that if your preferred waiter doesn't wake and claim its mutex before another wake occurs, you intend the grant to be lost. As I mentioned, sometimes you want that, sometimes you don't. I assume you'd like this sort of stuff documented? Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/