summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2004-04-06 19:17:46 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2004-04-06 19:17:46 +0000
commit9000d57d57642b9c07ad58cf32ad9dda2532cd8c (patch)
tree4a0a62119cab803f40317ae67cd3d91913ae1d00 /sys
parent535eb309628e9d94dda0a46be2834d944cc4337b (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_condvar.c15
-rw-r--r--sys/sys/condvar.h6
2 files changed, 18 insertions, 3 deletions
diff --git a/sys/kern/kern_condvar.c b/sys/kern/kern_condvar.c
index 6fff7e083e46..2b7bd970a573 100644
--- a/sys/kern/kern_condvar.c
+++ b/sys/kern/kern_condvar.c
@@ -65,6 +65,7 @@ cv_init(struct cv *cvp, const char *desc)
{
cvp->cv_description = desc;
+ cvp->cv_waiters = 0;
}
/*
@@ -119,6 +120,7 @@ cv_wait(struct cv *cvp, struct mtx *mp)
sq = sleepq_lookup(cvp);
+ cvp->cv_waiters++;
DROP_GIANT();
mtx_unlock(mp);
@@ -175,6 +177,7 @@ cv_wait_sig(struct cv *cvp, struct mtx *mp)
/* XXX: Missing the threading checks from msleep! */
+ cvp->cv_waiters++;
DROP_GIANT();
mtx_unlock(mp);
@@ -241,6 +244,7 @@ cv_timedwait(struct cv *cvp, struct mtx *mp, int timo)
sq = sleepq_lookup(cvp);
+ cvp->cv_waiters++;
DROP_GIANT();
mtx_unlock(mp);
@@ -299,6 +303,7 @@ cv_timedwait_sig(struct cv *cvp, struct mtx *mp, int timo)
sq = sleepq_lookup(cvp);
+ cvp->cv_waiters++;
DROP_GIANT();
mtx_unlock(mp);
@@ -341,7 +346,10 @@ void
cv_signal(struct cv *cvp)
{
- sleepq_signal(cvp, SLEEPQ_CONDVAR, -1);
+ if (cvp->cv_waiters > 0) {
+ cvp->cv_waiters--;
+ sleepq_signal(cvp, SLEEPQ_CONDVAR, -1);
+ }
}
/*
@@ -352,5 +360,8 @@ void
cv_broadcastpri(struct cv *cvp, int pri)
{
- sleepq_broadcast(cvp, SLEEPQ_CONDVAR, pri);
+ if (cvp->cv_waiters > 0) {
+ cvp->cv_waiters = 0;
+ sleepq_broadcast(cvp, SLEEPQ_CONDVAR, pri);
+ }
}
diff --git a/sys/sys/condvar.h b/sys/sys/condvar.h
index bb10beba9191..589fedd20a01 100644
--- a/sys/sys/condvar.h
+++ b/sys/sys/condvar.h
@@ -38,10 +38,14 @@ struct thread;
TAILQ_HEAD(cv_waitq, thread);
/*
- * Condition variable.
+ * Condition variable. The waiters count is protected by the mutex that
+ * protects the condition; that is, the mutex that is passed to cv_wait*()
+ * and is held across calls to cv_signal() and cv_broadcast(). It is an
+ * optimization to avoid looking up the sleep queue if there are no waiters.
*/
struct cv {
const char *cv_description;
+ int cv_waiters;
};
#ifdef _KERNEL