summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-03-21 20:46:26 +0000
committerjhb <jhb@FreeBSD.org>2007-03-21 20:46:26 +0000
commit4b65fa3cdb272192c39a0e5cf223f9fe71dff949 (patch)
tree2204e2e98cd36759b9367d076afb477c1dd2d7eb /sys/kern
parent8aefbb617959eb71f5ec34bd628b570fc029b63b (diff)
downloadFreeBSD-src-4b65fa3cdb272192c39a0e5cf223f9fe71dff949.zip
FreeBSD-src-4b65fa3cdb272192c39a0e5cf223f9fe71dff949.tar.gz
Don't use cv_wait_unlock() to implement cv_wait(). Instead, implement
cv_wait() fully and add missing KTRACE context switch traces.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_condvar.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/sys/kern/kern_condvar.c b/sys/kern/kern_condvar.c
index e7410e6..62e4f04 100644
--- a/sys/kern/kern_condvar.c
+++ b/sys/kern/kern_condvar.c
@@ -96,7 +96,16 @@ void
cv_wait(struct cv *cvp, struct mtx *mp)
{
WITNESS_SAVE_DECL(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);
WITNESS_SAVE(&mp->mtx_object, mp);
if (cold || panicstr) {
@@ -109,7 +118,21 @@ cv_wait(struct cv *cvp, struct mtx *mp)
return;
}
- cv_wait_unlock(cvp, mp);
+ sleepq_lock(cvp);
+
+ cvp->cv_waiters++;
+ DROP_GIANT();
+ mtx_unlock(mp);
+
+ sleepq_add(cvp, &mp->mtx_object, cvp->cv_description, SLEEPQ_CONDVAR,
+ 0);
+ sleepq_wait(cvp);
+
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_CSW))
+ ktrcsw(0, 0);
+#endif
+ PICKUP_GIANT();
mtx_lock(mp);
WITNESS_RESTORE(&mp->mtx_object, mp);
}
@@ -153,6 +176,10 @@ cv_wait_unlock(struct cv *cvp, struct mtx *mp)
0);
sleepq_wait(cvp);
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_CSW))
+ ktrcsw(0, 0);
+#endif
PICKUP_GIANT();
}
OpenPOWER on IntegriCloud