condvar and mutexes

Robert Watson rwatson at freebsd.org
Sun Jun 27 02:16:03 GMT 2004


On Sat, 26 Jun 2004, Nicolas Souchu wrote:

> Why is condvar(9) API not part of the mutex(9) one? A condvar is nothing
> more than a mutex with a queue of waiting threads. 
> 
> I would simply imagine some wait calls applied to mutexes with the queue
> in the mutex struct. 

A few observations:

- Combining it all into one man page would lead to an awfully long man
  page :-).

- If you use a condition variable, you must use a mutex.  However, if you
  use a mutex, there's no obligation to use a condition variable.  Most of
  our mutexes don't involve using condition variables, actually, I
  suspect.  Note that the wait queue for a mutex is not the same as a wait
  queue for a condition variable associated with the mutex.  As it stands,
  we get to choose when we do (and don't) want the additional overhead.

- I've used Mach's wait queue and mutex APIs, which seems to have a split
  more like what you're suggesting, and I have to say they are
  abysmal in terms of usability and avoiding races.  In fact, in some
  recent work to port some FreeBSD piecess to Darwin, which uses Mach's
  mutexes and wait queues, I implemented the FreeBSD condition variable
  API in terms of the Mach primitives rather than use the Mach primitives
  directly.  In particular, the cv_wait() interface in our API is much
  easier to use:

void
cv_wait(struct cv *cvp, mutex_t *mp)
{
        int ret;

        mutex_unlock(mp);
        ret = wait_queue_assert_wait(cvp->cv_wait_queue, 0, THREAD_UNINT);
        if (ret != THREAD_WAITING)
                panic("cv_wait: wait_queue_assert_wait failed");
        ret = thread_block(THREAD_CONTINUE_NULL);
        if (ret != THREAD_AWAKENED)
                panic("cv_wait: thread_block failed");
        mutex_lock(mp);
}

- By using an API that's congurent to the POSIX threads API in user space,
  we make it easier for developers familiar with existing synchronization
  primitives in user space to adapt to kernel synchronization.  And when
  someone says "How should I perform synchronization in kernel?", we can
  point them at the volumes of documentation on pthreads.  Note that our
  API is quite a bit simpler than pthreads, but most of the same issues
  apply (how to use condition variables, for example). 

Robert N M Watson             FreeBSD Core Team, TrustedBSD Projects
robert at fledge.watson.org      Principal Research Scientist, McAfee Research



More information about the freebsd-arch mailing list