From owner-freebsd-arch@FreeBSD.ORG Wed Dec 7 22:44:13 2005 Return-Path: X-Original-To: freebsd-arch@freebsd.org 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 0283116A41F; Wed, 7 Dec 2005 22:44:13 +0000 (GMT) (envelope-from rodrigc@crodrigues.org) Received: from sccrmhc13.comcast.net (sccrmhc13.comcast.net [204.127.202.64]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4D21243D5E; Wed, 7 Dec 2005 22:44:03 +0000 (GMT) (envelope-from rodrigc@crodrigues.org) Received: from c-24-63-58-245.hsd1.ma.comcast.net ([24.63.58.245]) by comcast.net (sccrmhc13) with ESMTP id <20051207224400013003gne7e>; Wed, 7 Dec 2005 22:44:01 +0000 Received: from c-24-63-58-245.hsd1.ma.comcast.net (localhost [127.0.0.1]) by c-24-63-58-245.hsd1.ma.comcast.net (8.13.4/8.13.1) with ESMTP id jB7Mi0gv004358; Wed, 7 Dec 2005 17:44:00 -0500 (EST) (envelope-from rodrigc@c-24-63-58-245.hsd1.ma.comcast.net) Received: (from rodrigc@localhost) by c-24-63-58-245.hsd1.ma.comcast.net (8.13.4/8.13.1/Submit) id jB7Mi0GK004344; Wed, 7 Dec 2005 17:44:00 -0500 (EST) (envelope-from rodrigc) Date: Wed, 7 Dec 2005 17:43:59 -0500 From: Craig Rodrigues To: freebsd-arch@freebsd.org Message-ID: <20051207224359.GA4320@crodrigues.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.1i Cc: Subject: [RFC] Implement cv_wait_nolock(), for emulation of SGI's sv_wait() X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Dec 2005 22:44:13 -0000 Hi, As part of the XFS for FreeBSD project, Alexander Kabaev implemented a cv_wait_nolock() function for compatibility with SGI's sv_wait() call: http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=0650&db=man&fname=/usr/share/catman/p_man/catD/SV_WAIT.z sv_wait() waits on a synchronization variable, the lock must be held before the call is entered, but the lock is not held when sv_wait() is exited. Is this patch OK to go into FreeBSD? Comments? Index: condvar.h =================================================================== RCS file: /home/ncvs/src/sys/sys/condvar.h,v retrieving revision 1.12 diff -u -u -r1.12 condvar.h --- condvar.h 5 May 2004 21:57:44 -0000 1.12 +++ condvar.h 7 Dec 2005 22:38:44 -0000 @@ -53,6 +53,7 @@ void cv_destroy(struct cv *cvp); void cv_wait(struct cv *cvp, struct mtx *mp); +void cv_wait_nolock(struct cv *cvp, struct mtx *mp); int cv_wait_sig(struct cv *cvp, struct mtx *mp); int cv_timedwait(struct cv *cvp, struct mtx *mp, int timo); int cv_timedwait_sig(struct cv *cvp, struct mtx *mp, int timo); Index: kern_condvar.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_condvar.c,v retrieving revision 1.52 diff -u -u -r1.52 kern_condvar.c --- kern_condvar.c 12 Oct 2004 18:36:19 -0000 1.52 +++ kern_condvar.c 7 Dec 2005 22:39:25 -0000 @@ -137,6 +137,46 @@ } /* + * Wait on a condition variable. This function differs from cv_wait by + * not aquiring the mutex after condition variable was signaled. + */ +void +cv_wait_nolock(struct cv *cvp, struct mtx *mp) +{ + struct thread *td; + + td = curthread; +#ifdef KTRACE + if (KTRPOINT(td, KTR_CSW)) + ktrcsw(1, 0); +#endif + CV_ASSERT(cvp, mp, td); + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, &mp->mtx_object, + "Waiting on \"%s\"", cvp->cv_description); + + if (cold || panicstr) { + /* + * During autoconfiguration, just give interrupts + * a chance, then just return. Don't run any other + * thread or panic below, in case this is the idle + * process and already asleep. + */ + return; + } + + sleepq_lock(cvp); + + cvp->cv_waiters++; + DROP_GIANT(); + mtx_unlock(mp); + + sleepq_add(cvp, mp, cvp->cv_description, SLEEPQ_CONDVAR); + sleepq_wait(cvp); + + PICKUP_GIANT(); +} + +/* * Wait on a condition variable, allowing interruption by signals. Return 0 if * the thread was resumed with cv_signal or cv_broadcast, EINTR or ERESTART if * a signal was caught. If ERESTART is returned the system call should be -- Craig Rodrigues rodrigc@crodrigues.org