Subject: Condition variables
To: None <tech-kern@netbsd.org>
From: Jason R Thorpe <thorpej@zembu.com>
List: tech-kern
Date: 06/05/2000 16:15:33
Hi folks...

I have written a condition variable implementation for the NetBSD kernel,
based on the tsleep() implementation.  For those of you unfamiliar with
condition variables, a condition variable is like a tsleep() "wait channel",
except it is separate from the thing you're waiting for (e.g. if you're
waiting for a VM page, you wait on `&pg->condvar', not `pg').  If you've
ever programmed in pthreads, you understand how this all works.

These are important in an SMP environment for eliminating race conditions
between a thread blocking and another thread unblocking blocked threads; when
you block on a condition variable, you pass an interlock that is not released
until you are on the sleep queue.

The API is pretty straightforward:

void	cond_init(condvar_t *cv, const char *name);
int	cond_wait(condvar_t *cv, int prio, int timo,
	    __volatile struct simplelock *interlock);
void	cond_signal(condvar_t *cv);
void	cond_broadcast(condvar_t *cv);

The `prio' and `timo' arguments to cond_wait() are the same as the
corresponding arguments for tsleep().  A new `prio' flag has also
been added, PNORELOCK, to prevent the thread from attempting to
relock the interlock when it is unblocked.

I am currently running a lockmgr() that uses condition variables, and
also a mostly condition variable'ized UVM at the moment.  All is well.

After a little more testing and review by a couple of people, I plan
on committing this, within the next day or two.

-- 
        -- Jason R. Thorpe <thorpej@zembu.com>