summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrodrigc <rodrigc@FreeBSD.org>2005-12-12 00:02:22 +0000
committerrodrigc <rodrigc@FreeBSD.org>2005-12-12 00:02:22 +0000
commit4377e3b906f68937a8dca335993c27b24923c9c3 (patch)
tree193e281b1a05b4ca90f96954bb92e5d56807fc8a
parent16b60b222455d355c26bee796cfca71f5b34f6cc (diff)
downloadFreeBSD-src-4377e3b906f68937a8dca335993c27b24923c9c3.zip
FreeBSD-src-4377e3b906f68937a8dca335993c27b24923c9c3.tar.gz
Contributions from XFS for FreeBSD project:
- Implement cv_wait_unlock() method which has semantics compatible with the sv_wait() method in IRIX. For cv_wait_unlock(), the lock must be held before entering the function, but is not held when the function is exited. - Implement the existing cv_wait() function in terms of cv_wait_unlock(). Submitted by: kan Feedback from: jhb, trhodes, Christoph Hellwig <hch at infradead dot org>
-rw-r--r--sys/kern/kern_condvar.c35
-rw-r--r--sys/sys/condvar.h1
2 files changed, 28 insertions, 8 deletions
diff --git a/sys/kern/kern_condvar.c b/sys/kern/kern_condvar.c
index 8ccea3a..ede6b61 100644
--- a/sys/kern/kern_condvar.c
+++ b/sys/kern/kern_condvar.c
@@ -95,9 +95,34 @@ cv_destroy(struct cv *cvp)
void
cv_wait(struct cv *cvp, struct mtx *mp)
{
- struct thread *td;
WITNESS_SAVE_DECL(mp);
+ WITNESS_SAVE(&mp->mtx_object, mp);
+
+ 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;
+ }
+
+ cv_wait_unlock(cvp, mp);
+ mtx_lock(mp);
+ WITNESS_RESTORE(&mp->mtx_object, mp);
+}
+
+/*
+ * Wait on a condition variable. This function differs from cv_wait by
+ * not aquiring the mutex after condition variable was signaled.
+ */
+void
+cv_wait_unlock(struct cv *cvp, struct mtx *mp)
+{
+ struct thread *td;
+
td = curthread;
#ifdef KTRACE
if (KTRPOINT(td, KTR_CSW))
@@ -106,7 +131,6 @@ cv_wait(struct cv *cvp, struct mtx *mp)
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) {
/*
@@ -115,6 +139,7 @@ cv_wait(struct cv *cvp, struct mtx *mp)
* thread or panic below, in case this is the idle
* process and already asleep.
*/
+ mtx_unlock(mp);
return;
}
@@ -127,13 +152,7 @@ cv_wait(struct cv *cvp, struct mtx *mp)
sleepq_add(cvp, mp, cvp->cv_description, SLEEPQ_CONDVAR);
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);
}
/*
diff --git a/sys/sys/condvar.h b/sys/sys/condvar.h
index a8c9db7..97f699a 100644
--- a/sys/sys/condvar.h
+++ b/sys/sys/condvar.h
@@ -53,6 +53,7 @@ void cv_init(struct cv *cvp, const char *desc);
void cv_destroy(struct cv *cvp);
void cv_wait(struct cv *cvp, struct mtx *mp);
+void cv_wait_unlock(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);
OpenPOWER on IntegriCloud