[RFC] Implement cv_wait_nolock(), for emulation of SGI's sv_wait()

Craig Rodrigues rodrigc at crodrigues.org
Wed Dec 7 14:44:13 PST 2005


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 at crodrigues.org


More information about the freebsd-arch mailing list