From owner-freebsd-arch@FreeBSD.ORG Sun Jun 27 02:16:03 2004 Return-Path: Delivered-To: freebsd-arch@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 59FD316A4CE for ; Sun, 27 Jun 2004 02:16:03 +0000 (GMT) Received: from fledge.watson.org (fledge.watson.org [204.156.12.50]) by mx1.FreeBSD.org (Postfix) with ESMTP id DFDCF43D1F for ; Sun, 27 Jun 2004 02:16:02 +0000 (GMT) (envelope-from robert@fledge.watson.org) Received: from fledge.watson.org (localhost [127.0.0.1]) by fledge.watson.org (8.12.11/8.12.11) with ESMTP id i5R2F9Yf066536; Sat, 26 Jun 2004 22:15:09 -0400 (EDT) (envelope-from robert@fledge.watson.org) Received: from localhost (robert@localhost)i5R2F9Yv066533; Sat, 26 Jun 2004 22:15:09 -0400 (EDT) (envelope-from robert@fledge.watson.org) Date: Sat, 26 Jun 2004 22:15:09 -0400 (EDT) From: Robert Watson X-Sender: robert@fledge.watson.org To: Nicolas Souchu In-Reply-To: <20040626234219.A7461@armor.freesurf.fr> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: freebsd-arch@freebsd.org Subject: Re: condvar and mutexes X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 27 Jun 2004 02:16:03 -0000 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@fledge.watson.org Principal Research Scientist, McAfee Research