diff options
author | jhb <jhb@FreeBSD.org> | 2007-03-21 20:46:26 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2007-03-21 20:46:26 +0000 |
commit | 4b65fa3cdb272192c39a0e5cf223f9fe71dff949 (patch) | |
tree | 2204e2e98cd36759b9367d076afb477c1dd2d7eb /sys/kern | |
parent | 8aefbb617959eb71f5ec34bd628b570fc029b63b (diff) | |
download | FreeBSD-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.c | 29 |
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(); } |