On Fri, Jun 09, 2006 at 03:24:00PM -0400, Peter Memishian wrote: > > > Whether this is good or bad, this is the official requirement. A quote > from > > the condvar(9F): > > > > cv_signal() signals the condition and wakes one blocked > > thread. All blocked threads can be unblocked by calling > > cv_broadcast(). You must acquire the mutex passed into > > cv_wait() before calling cv_signal() or cv_broadcast(). > > Further, cond_signal(3C) states: > > The cond_broadcast() function unblocks all threads that are > blocked on the condition variable pointed to by cvp. > > If no threads are blocked on the condition variable, then > cond_signal() and cond_broadcast() have no effect. > > Both functions should be called under the protection of the > same mutex that is used with the condition variable being > signaled. Otherwise, the condition variable may be signaled > between the test of the associated condition and blocking in > cond_wait(). This can cause an infinite wait. > > ... but that rationale looks bogus to me. In particular, the thread > heading into cond_wait() must have already tested the condition under the > lock and concluded it was false in order to decide to cond_wait(). Since > any thread changing state that would affect the condition must also be > holding the lock, there is no way for the state (and thus the outcome of > the test) to change beween the test and the cond_wait(), and thus any > cond_signal() sent during that window would end up being spurious anyway. > > Please feel free to prove me wrong :-)
If I remember correctly, the main problems you can run into with signaling after dropping the lock is that there can be destruction races: thread 1 Thread 2 mutex_exit(&obj->mutex) --------------------------> mutex_enter(&obj->mutex) set up object for destruction mutex_exit(&obj->mutex) kmem_free(obj); <-------------------------- cv_signal(&obj->cv); I agree that the argument in cond_signal(3C) is bogus; the standard states that "signaling under the lock can make scheduling more deterministic", but it doesn't require anyone to do so. See pthread_cond_signal(3C): The pthread_cond_signal() or pthread_cond_broadcast() func- tions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_cond_timedwait() have associated with the condition variable during their waits; however, if predictable scheduling behavior is required, then that mutex is locked by the thread calling pthread_cond_signal() or pthread_cond_broadcast(). Cheers, - jonathan -- Jonathan Adams, Solaris Kernel Development