cvs commit: src/sys/vm vm_zeroidle.c

David Schultz das at FreeBSD.ORG
Mon Nov 8 14:33:41 PST 2004

On Mon, Nov 08, 2004, John Baldwin wrote:
> > The mutex associated with the condition variable will be held on
> > entry to both cv_wait() and cv_signal(), so why is the sleepqueue
> > locked in the no waiters case?
> It is no longer required to hold the mutex over cv_wait() and cv_signal().  I 
> intentionally changed that so that you can do:
> 	lock()
> 	blah()
> 	unlock()
> 	cv_signal()
> and reduce the number of context switches if you preempt in cv_signal().

Hmm...I agree with Alfred that allowing this is a bad idea.  By
permitting this, you're adding two additional mutex operations to
the critical path in order to avoid an inefficiency that will
almost never occur.

Suppose that the cv_signal() is done immediately *before* the unlock
operation.  The odds that the signalling thread is preempted in a
the few cycles between the cv_signal() and the unlock are close to
nil.  Furthermore, on a multiprocessor, it will take longer for
another processor to schedule one of the waiters than it will for
the signalling processor to release the lock.

The original formulation of this kind of condition variable was in
Mesa[1], which requires the lock to be held during cv_signal()
specifically for efficiency.[2]  Solaris also requires the mutex to
be held across cv_signal().  PThreads is the only API I know of to
have it the other way around.


[2] It supported a second, less efficient type of CV that would
    allow device microcode to signal device drivers without
    holding the mutex, but all other CVs required the mutex to be
    held when the CV was signalled.  But this second kind of CV
    is irrelevant today.

More information about the cvs-all mailing list