Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Dec 2008 20:03:15 +0000 (UTC)
From:      Kip Macy <kmacy@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r185618 - in projects/release_6_3_xen/sys: kern sys
Message-ID:  <200812042003.mB4K3FD7032837@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kmacy
Date: Thu Dec  4 20:03:15 2008
New Revision: 185618
URL: http://svn.freebsd.org/changeset/base/185618

Log:
  integrate generic sleepq_add and _sleep in order to implement sx_sleep

Modified:
  projects/release_6_3_xen/sys/kern/init_main.c
  projects/release_6_3_xen/sys/kern/kern_condvar.c
  projects/release_6_3_xen/sys/kern/kern_lock.c
  projects/release_6_3_xen/sys/kern/kern_mutex.c
  projects/release_6_3_xen/sys/kern/kern_rwlock.c
  projects/release_6_3_xen/sys/kern/kern_sx.c
  projects/release_6_3_xen/sys/kern/kern_synch.c
  projects/release_6_3_xen/sys/kern/subr_sleepqueue.c
  projects/release_6_3_xen/sys/sys/lock.h
  projects/release_6_3_xen/sys/sys/sleepqueue.h
  projects/release_6_3_xen/sys/sys/systm.h

Modified: projects/release_6_3_xen/sys/kern/init_main.c
==============================================================================

Modified: projects/release_6_3_xen/sys/kern/kern_condvar.c
==============================================================================
--- projects/release_6_3_xen/sys/kern/kern_condvar.c	Thu Dec  4 18:48:08 2008	(r185617)
+++ projects/release_6_3_xen/sys/kern/kern_condvar.c	Thu Dec  4 20:03:15 2008	(r185618)
@@ -124,7 +124,7 @@ cv_wait(struct cv *cvp, struct mtx *mp)
 	DROP_GIANT();
 	mtx_unlock(mp);
 
-	sleepq_add(cvp, mp, cvp->cv_description, SLEEPQ_CONDVAR, 0);
+	sleepq_add(cvp, &mp->mtx_object, cvp->cv_description, SLEEPQ_CONDVAR, 0);
 	sleepq_wait(cvp);
 
 #ifdef KTRACE
@@ -177,7 +177,7 @@ cv_wait_sig(struct cv *cvp, struct mtx *
 	DROP_GIANT();
 	mtx_unlock(mp);
 
-	sleepq_add(cvp, mp, cvp->cv_description, SLEEPQ_CONDVAR |
+	sleepq_add(cvp, &mp->mtx_object, cvp->cv_description, SLEEPQ_CONDVAR |
 	    SLEEPQ_INTERRUPTIBLE, 0);
 	rval = sleepq_wait_sig(cvp);
 
@@ -231,7 +231,7 @@ cv_timedwait(struct cv *cvp, struct mtx 
 	DROP_GIANT();
 	mtx_unlock(mp);
 
-	sleepq_add(cvp, mp, cvp->cv_description, SLEEPQ_CONDVAR, 0);
+	sleepq_add(cvp, &mp->mtx_object, cvp->cv_description, SLEEPQ_CONDVAR, 0);
 	sleepq_set_timeout(cvp, timo);
 	rval = sleepq_timedwait(cvp);
 
@@ -288,7 +288,7 @@ cv_timedwait_sig(struct cv *cvp, struct 
 	DROP_GIANT();
 	mtx_unlock(mp);
 
-	sleepq_add(cvp, mp, cvp->cv_description, SLEEPQ_CONDVAR |
+	sleepq_add(cvp, &mp->mtx_object, cvp->cv_description, SLEEPQ_CONDVAR |
 	    SLEEPQ_INTERRUPTIBLE, 0);
 	sleepq_set_timeout(cvp, timo);
 	rval = sleepq_timedwait_sig(cvp);

Modified: projects/release_6_3_xen/sys/kern/kern_lock.c
==============================================================================
--- projects/release_6_3_xen/sys/kern/kern_lock.c	Thu Dec  4 18:48:08 2008	(r185617)
+++ projects/release_6_3_xen/sys/kern/kern_lock.c	Thu Dec  4 20:03:15 2008	(r185618)
@@ -62,6 +62,43 @@ __FBSDID("$FreeBSD$");
 #include <ddb/ddb.h>
 #endif
 
+
+#ifdef DDB
+#include <ddb/ddb.h>
+static void	db_show_lockmgr(struct lock_object *lock);
+#endif
+static void	lock_lockmgr(struct lock_object *lock, int how);
+static int	unlock_lockmgr(struct lock_object *lock);
+
+struct lock_class lock_class_lockmgr = {
+	.lc_name = "lockmgr",
+	.lc_flags = LC_SLEEPLOCK | LC_SLEEPABLE | LC_RECURSABLE | LC_UPGRADABLE,
+#ifdef DDB
+	.lc_ddb_show = db_show_lockmgr,
+#endif
+	.lc_lock = lock_lockmgr,
+	.lc_unlock = unlock_lockmgr,
+};
+
+/*
+ * Locking primitives implementation.
+ * Locks provide shared/exclusive sychronization.
+ */
+
+void
+lock_lockmgr(struct lock_object *lock, int how)
+{
+
+	panic("lockmgr locks do not support sleep interlocking");
+}
+
+int
+unlock_lockmgr(struct lock_object *lock)
+{
+
+	panic("lockmgr locks do not support sleep interlocking");
+}
+
 /*
  * Locking primitives implementation.
  * Locks provide shared/exclusive sychronization.
@@ -639,14 +676,13 @@ ok:
 	return (1);
 }
 
-DB_SHOW_COMMAND(lockmgr, db_show_lockmgr)
+void
+db_show_lockmgr(struct lock_object *lock)
 {
 	struct thread *td;
 	struct lock *lkp;
 
-	if (!have_addr)
-		return;
-	lkp = (struct lock *)addr;
+	lkp = (struct lock *)lock;
 
 	db_printf("lock type: %s\n", lkp->lk_wmesg);
 	db_printf("state: ");

Modified: projects/release_6_3_xen/sys/kern/kern_mutex.c
==============================================================================
--- projects/release_6_3_xen/sys/kern/kern_mutex.c	Thu Dec  4 18:48:08 2008	(r185617)
+++ projects/release_6_3_xen/sys/kern/kern_mutex.c	Thu Dec  4 20:03:15 2008	(r185618)
@@ -92,25 +92,66 @@ __FBSDID("$FreeBSD$");
 #ifdef DDB
 static void	db_show_mtx(struct lock_object *lock);
 #endif
+static void	lock_mtx(struct lock_object *lock, int how);
+static void	lock_spin(struct lock_object *lock, int how);
+static int	unlock_mtx(struct lock_object *lock);
+static int	unlock_spin(struct lock_object *lock);
+
 
 /*
  * Lock classes for sleep and spin mutexes.
  */
 struct lock_class lock_class_mtx_sleep = {
-	"sleep mutex",
-	LC_SLEEPLOCK | LC_RECURSABLE,
+	.lc_name = "sleep mutex",
+	.lc_flags = LC_SLEEPLOCK | LC_RECURSABLE,
 #ifdef DDB
-	db_show_mtx
+	.lc_ddb_show = db_show_mtx,
 #endif
+	.lc_lock = lock_mtx,
+	.lc_unlock = unlock_mtx,
 };
 struct lock_class lock_class_mtx_spin = {
-	"spin mutex",
-	LC_SPINLOCK | LC_RECURSABLE,
+	.lc_name = "spin mutex",
+	.lc_flags = LC_SPINLOCK | LC_RECURSABLE,
 #ifdef DDB
-	db_show_mtx
+	.lc_ddb_show = db_show_mtx,
 #endif
+	.lc_lock = lock_spin,
+	.lc_unlock = unlock_spin,
 };
 
+void
+lock_mtx(struct lock_object *lock, int how)
+{
+
+	mtx_lock((struct mtx *)lock);
+}
+
+void
+lock_spin(struct lock_object *lock, int how)
+{
+
+	panic("spin locks can only use msleep_spin");
+}
+
+int
+unlock_mtx(struct lock_object *lock)
+{
+	struct mtx *m;
+
+	m = (struct mtx *)lock;
+	mtx_assert(m, MA_OWNED | MA_NOTRECURSED);
+	mtx_unlock(m);
+	return (0);
+}
+
+int
+unlock_spin(struct lock_object *lock)
+{
+
+	panic("spin locks can only use msleep_spin");
+}
+
 /*
  * System-wide mutexes
  */

Modified: projects/release_6_3_xen/sys/kern/kern_rwlock.c
==============================================================================
--- projects/release_6_3_xen/sys/kern/kern_rwlock.c	Thu Dec  4 18:48:08 2008	(r185617)
+++ projects/release_6_3_xen/sys/kern/kern_rwlock.c	Thu Dec  4 20:03:15 2008	(r185618)
@@ -60,13 +60,19 @@ CTASSERT((RW_RECURSE & LO_CLASSFLAGS) ==
 static void	db_show_rwlock(struct lock_object *lock);
 #endif
 
+static void	lock_rw(struct lock_object *lock, int how);
+static int	unlock_rw(struct lock_object *lock);
+
 struct lock_class lock_class_rw = {
 	.lc_name = "rw",
 	.lc_flags = LC_SLEEPLOCK | LC_RECURSABLE | LC_UPGRADABLE,
 #ifdef DDB
 	.lc_ddb_show = db_show_rwlock,
 #endif
+	.lc_lock = lock_rw,
+	.lc_unlock = unlock_rw
 };
+      
 
 /*
  * Return a pointer to the owning thread if the lock is write-locked or
@@ -99,6 +105,34 @@ struct lock_class lock_class_rw = {
 #endif
 
 void
+lock_rw(struct lock_object *lock, int how)
+{
+	struct rwlock *rw;
+
+	rw = (struct rwlock *)lock;
+	if (how)
+		rw_wlock(rw);
+	else
+		rw_rlock(rw);
+}
+
+int
+unlock_rw(struct lock_object *lock)
+{
+	struct rwlock *rw;
+
+	rw = (struct rwlock *)lock;
+	rw_assert(rw, RA_LOCKED | LA_NOTRECURSED);
+	if (rw->rw_lock & RW_LOCK_READ) {
+		rw_runlock(rw);
+		return (0);
+	} else {
+		rw_wunlock(rw);
+		return (1);
+	}
+}
+
+void
 rw_init_flags(struct rwlock *rw, const char *name, int opts)
 {
 	int flags;

Modified: projects/release_6_3_xen/sys/kern/kern_sx.c
==============================================================================
--- projects/release_6_3_xen/sys/kern/kern_sx.c	Thu Dec  4 18:48:08 2008	(r185617)
+++ projects/release_6_3_xen/sys/kern/kern_sx.c	Thu Dec  4 20:03:15 2008	(r185618)
@@ -107,12 +107,17 @@ CTASSERT(((SX_ADAPTIVESPIN | SX_RECURSE)
 static void	db_show_sx(struct lock_object *lock);
 #endif
 
+static void	lock_sx(struct lock_object *lock, int how);
+static int	unlock_sx(struct lock_object *lock);
+
 struct lock_class lock_class_sx = {
 	.lc_name = "sx",
 	.lc_flags = LC_SLEEPLOCK | LC_SLEEPABLE | LC_RECURSABLE | LC_UPGRADABLE,
 #ifdef DDB
 	.lc_ddb_show = db_show_sx,
 #endif
+	.lc_lock = lock_sx,
+	.lc_unlock = unlock_sx,
 };
 
 #ifndef INVARIANTS
@@ -120,6 +125,34 @@ struct lock_class lock_class_sx = {
 #endif
 
 void
+lock_sx(struct lock_object *lock, int how)
+{
+	struct sx *sx;
+
+	sx = (struct sx *)lock;
+	if (how)
+		sx_xlock(sx);
+	else
+		sx_slock(sx);
+}
+
+int
+unlock_sx(struct lock_object *lock)
+{
+	struct sx *sx;
+
+	sx = (struct sx *)lock;
+	sx_assert(sx, SA_LOCKED | SA_NOTRECURSED);
+	if (sx_xlocked(sx)) {
+		sx_xunlock(sx);
+		return (1);
+	} else {
+		sx_sunlock(sx);
+		return (0);
+	}
+}
+
+void
 sx_sysinit(void *arg)
 {
 	struct sx_args *sargs = arg;

Modified: projects/release_6_3_xen/sys/kern/kern_synch.c
==============================================================================
--- projects/release_6_3_xen/sys/kern/kern_synch.c	Thu Dec  4 18:48:08 2008	(r185617)
+++ projects/release_6_3_xen/sys/kern/kern_synch.c	Thu Dec  4 20:03:15 2008	(r185618)
@@ -75,6 +75,7 @@ SYSINIT(synch_setup, SI_SUB_KICK_SCHEDUL
 
 int	hogticks;
 int	lbolt;
+static int pause_wchan;
 
 static struct callout loadav_callout;
 static struct callout lbolt_callout;
@@ -106,6 +107,143 @@ sleepinit(void)
 	init_sleepqueues();
 }
 
+
+/*
+ * General sleep call.  Suspends the current thread until a wakeup is
+ * performed on the specified identifier.  The thread will then be made
+ * runnable with the specified priority.  Sleeps at most timo/hz seconds
+ * (0 means no timeout).  If pri includes PCATCH flag, signals are checked
+ * before and after sleeping, else signals are not checked.  Returns 0 if
+ * awakened, EWOULDBLOCK if the timeout expires.  If PCATCH is set and a
+ * signal needs to be delivered, ERESTART is returned if the current system
+ * call should be restarted if possible, and EINTR is returned if the system
+ * call should be interrupted by the signal (return EINTR).
+ *
+ * The lock argument is unlocked before the caller is suspended, and
+ * re-locked before _sleep() returns.  If priority includes the PDROP
+ * flag the lock is not re-locked before returning.
+ */
+int
+_sleep(void *ident, struct lock_object *lock, int priority,
+    const char *wmesg, int timo)
+{
+	struct thread *td;
+	struct proc *p;
+	struct lock_class *class;
+	int catch, flags, lock_state, pri, rval;
+	WITNESS_SAVE_DECL(lock_witness);
+
+	td = curthread;
+	p = td->td_proc;
+#ifdef KTRACE
+	if (KTRPOINT(td, KTR_CSW))
+		ktrcsw(1, 0);
+#endif
+	WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock,
+	    "Sleeping on \"%s\"", wmesg);
+	KASSERT(timo != 0 || mtx_owned(&Giant) || lock != NULL ||
+	    ident == &lbolt, ("sleeping without a lock"));
+	KASSERT(p != NULL, ("msleep1"));
+	KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep"));
+	if (lock != NULL)
+		class = LOCK_CLASS(lock);
+	else
+		class = NULL;
+
+	if (cold) {
+		/*
+		 * During autoconfiguration, just return;
+		 * don't run any other threads or panic below,
+		 * in case this is the idle thread and already asleep.
+		 * XXX: this used to do "s = splhigh(); splx(safepri);
+		 * splx(s);" to give interrupts a chance, but there is
+		 * no way to give interrupts a chance now.
+		 */
+		if (lock != NULL && priority & PDROP)
+			class->lc_unlock(lock);
+		return (0);
+	}
+	catch = priority & PCATCH;
+	rval = 0;
+
+	/*
+	 * If we are already on a sleep queue, then remove us from that
+	 * sleep queue first.  We have to do this to handle recursive
+	 * sleeps.
+	 */
+	if (TD_ON_SLEEPQ(td))
+		sleepq_remove(td, td->td_wchan);
+
+	if (ident == &pause_wchan)
+		flags = SLEEPQ_PAUSE;
+	else
+		flags = SLEEPQ_SLEEP;
+	if (catch)
+		flags |= SLEEPQ_INTERRUPTIBLE;
+
+	sleepq_lock(ident);
+	CTR5(KTR_PROC, "sleep: thread %ld (pid %ld, %s) on %s (%p)",
+	    td->td_tid, p->p_pid, p->p_comm, wmesg, ident);
+
+	DROP_GIANT();
+	if (lock != NULL && !(class->lc_flags & LC_SLEEPABLE)) {
+		WITNESS_SAVE(lock, lock_witness);
+		lock_state = class->lc_unlock(lock);
+	} else
+		/* GCC needs to follow the Yellow Brick Road */
+		lock_state = -1;
+
+	/*
+	 * We put ourselves on the sleep queue and start our timeout
+	 * before calling thread_suspend_check, as we could stop there,
+	 * and a wakeup or a SIGCONT (or both) could occur while we were
+	 * stopped without resuming us.  Thus, we must be ready for sleep
+	 * when cursig() is called.  If the wakeup happens while we're
+	 * stopped, then td will no longer be on a sleep queue upon
+	 * return from cursig().
+	 */
+	sleepq_add(ident, ident == &lbolt ? NULL : lock, wmesg, flags, 0);
+	if (timo)
+		sleepq_set_timeout(ident, timo);
+	if (lock != NULL && class->lc_flags & LC_SLEEPABLE) {
+		sleepq_release(ident);
+		WITNESS_SAVE(lock, lock_witness);
+		lock_state = class->lc_unlock(lock);
+		sleepq_lock(ident);
+	}
+
+	/*
+	 * Adjust this thread's priority, if necessary.
+	 */
+	pri = priority & PRIMASK;
+	if (pri != 0 && pri != td->td_priority) {
+		mtx_lock_spin(&sched_lock);
+		sched_prio(td, pri);
+		mtx_unlock_spin(&sched_lock);
+	}
+
+	if (timo && catch)
+		rval = sleepq_timedwait_sig(ident);
+	else if (timo)
+		rval = sleepq_timedwait(ident);
+	else if (catch)
+		rval = sleepq_wait_sig(ident);
+	else {
+		sleepq_wait(ident);
+		rval = 0;
+	}
+#ifdef KTRACE
+	if (KTRPOINT(td, KTR_CSW))
+		ktrcsw(0, 0);
+#endif
+	PICKUP_GIANT();
+	if (lock != NULL && !(priority & PDROP)) {
+		class->lc_lock(lock, lock_state);
+		WITNESS_RESTORE(lock, lock_witness);
+	}
+	return (rval);
+}
+
 /*
  * General sleep call.  Suspends the current process until a wakeup is
  * performed on the specified identifier.  The process will then be made
@@ -170,7 +308,7 @@ msleep(ident, mtx, priority, wmesg, timo
 	if (TD_ON_SLEEPQ(td))
 		sleepq_remove(td, td->td_wchan);
 
-	flags = SLEEPQ_MSLEEP;
+	flags = SLEEPQ_SLEEP;
 	if (catch)
 		flags |= SLEEPQ_INTERRUPTIBLE;
 
@@ -194,7 +332,7 @@ msleep(ident, mtx, priority, wmesg, timo
 	 * stopped, then td will no longer be on a sleep queue upon
 	 * return from cursig().
 	 */
-	sleepq_add(ident, mtx, wmesg, flags, 0);
+	sleepq_add(ident, &mtx->mtx_object, wmesg, flags, 0);
 	if (timo)
 		sleepq_set_timeout(ident, timo);
 
@@ -271,7 +409,7 @@ msleep_spin(ident, mtx, wmesg, timo)
 	/*
 	 * We put ourselves on the sleep queue and start our timeout.
 	 */
-	sleepq_add(ident, mtx, wmesg, SLEEPQ_MSLEEP, 0);
+	sleepq_add(ident, &mtx->mtx_object, wmesg, SLEEPQ_SLEEP, 0);
 	if (timo)
 		sleepq_set_timeout(ident, timo);
 
@@ -320,7 +458,7 @@ wakeup(ident)
 {
 
 	sleepq_lock(ident);
-	sleepq_broadcast(ident, SLEEPQ_MSLEEP, -1, 0);
+	sleepq_broadcast(ident, SLEEPQ_SLEEP, -1, 0);
 }
 
 /*
@@ -334,7 +472,7 @@ wakeup_one(ident)
 {
 
 	sleepq_lock(ident);
-	sleepq_signal(ident, SLEEPQ_MSLEEP, -1, 0);
+	sleepq_signal(ident, SLEEPQ_SLEEP, -1, 0);
 }
 
 /*

Modified: projects/release_6_3_xen/sys/kern/subr_sleepqueue.c
==============================================================================
--- projects/release_6_3_xen/sys/kern/subr_sleepqueue.c	Thu Dec  4 18:48:08 2008	(r185617)
+++ projects/release_6_3_xen/sys/kern/subr_sleepqueue.c	Thu Dec  4 20:03:15 2008	(r185618)
@@ -121,7 +121,7 @@ struct sleepqueue {
 	void	*sq_wchan;			/* (c) Wait channel. */
 #ifdef INVARIANTS
 	int	sq_type;			/* (c) Queue type. */
-	struct mtx *sq_lock;		/* (c) Associated lock. */
+	struct lock_object *sq_lock;		/* (c) Associated lock. */
 #endif
 };
 
@@ -270,7 +270,7 @@ sleepq_release(void *wchan)
  * woken up.
  */
 void
-sleepq_add(void *wchan, struct mtx *lock, const char *wmesg, int flags,
+sleepq_add(void *wchan, struct lock_object *lock, const char *wmesg, int flags,
     int queue)
 {
 	struct sleepqueue_chain *sc;
@@ -947,7 +947,7 @@ found:
 #ifdef INVARIANTS
 	db_printf("Queue type: %d\n", sq->sq_type);
 	if (sq->sq_lock) {
-		lock = &sq->sq_lock->mtx_object;
+		lock = sq->sq_lock;
 		db_printf("Associated Interlock: %p - (%s) %s\n", lock,
 		    LOCK_CLASS(lock)->lc_name, lock->lo_name);
 	}

Modified: projects/release_6_3_xen/sys/sys/lock.h
==============================================================================
--- projects/release_6_3_xen/sys/sys/lock.h	Thu Dec  4 18:48:08 2008	(r185617)
+++ projects/release_6_3_xen/sys/sys/lock.h	Thu Dec  4 20:03:15 2008	(r185618)
@@ -51,6 +51,8 @@ struct lock_class {
 	const	char *lc_name;
 	u_int	lc_flags;
 	void	(*lc_ddb_show)(struct lock_object *lock);
+	void	(*lc_lock)(struct lock_object *lock, int how);
+	int	(*lc_unlock)(struct lock_object *lock);
 };
 
 #define	LC_SLEEPLOCK	0x00000001	/* Sleep lock. */

Modified: projects/release_6_3_xen/sys/sys/sleepqueue.h
==============================================================================
--- projects/release_6_3_xen/sys/sys/sleepqueue.h	Thu Dec  4 18:48:08 2008	(r185617)
+++ projects/release_6_3_xen/sys/sys/sleepqueue.h	Thu Dec  4 20:03:15 2008	(r185618)
@@ -83,14 +83,16 @@ struct thread;
 #ifdef _KERNEL
 
 #define	SLEEPQ_TYPE		0x0ff		/* Mask of sleep queue types. */
-#define	SLEEPQ_MSLEEP		0x00		/* Used by msleep/wakeup. */
+#define	SLEEPQ_SLEEP		0x00		/* Used by msleep/wakeup. */
 #define	SLEEPQ_CONDVAR		0x01		/* Used for a cv. */
+#define	SLEEPQ_PAUSE		0x02		/* Used by pause. */
 #define	SLEEPQ_SX		0x03		/* Used by an sx lock. */
 #define	SLEEPQ_INTERRUPTIBLE	0x100		/* Sleep is interruptible. */
 
+
 void	init_sleepqueues(void);
 void	sleepq_abort(struct thread *td, int intrval);
-void	sleepq_add(void *, struct mtx *, const char *, int, int);
+void	sleepq_add(void *, struct lock_object *, const char *, int, int);
 struct sleepqueue *sleepq_alloc(void);
 void	sleepq_broadcast(void *, int, int, int);
 void	sleepq_free(struct sleepqueue *);

Modified: projects/release_6_3_xen/sys/sys/systm.h
==============================================================================
--- projects/release_6_3_xen/sys/sys/systm.h	Thu Dec  4 18:48:08 2008	(r185617)
+++ projects/release_6_3_xen/sys/sys/systm.h	Thu Dec  4 20:03:15 2008	(r185618)
@@ -113,6 +113,7 @@ extern char **kenvp;
  * General function declarations.
  */
 
+struct lock_object;
 struct clockframe;
 struct malloc_type;
 struct mtx;
@@ -295,6 +296,8 @@ static __inline void		splx(intrmask_t ip
  * Common `proc' functions are declared here so that proc.h can be included
  * less often.
  */
+int	_sleep(void *chan, struct lock_object *lock, int pri, const char *wmesg,
+	    int timo) __nonnull(1);
 int	msleep(void *chan, struct mtx *mtx, int pri, const char *wmesg,
 	    int timo);
 int	msleep_spin(void *chan, struct mtx *mtx, const char *wmesg, int timo);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812042003.mB4K3FD7032837>