PERFORCE change 100185 for review
Kip Macy
kmacy at FreeBSD.org
Wed Jun 28 04:45:45 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=100185
Change 100185 by kmacy at kmacy_storage:sun4v_work_sleepq on 2006/06/28 04:44:46
add support for LK_DRAIN semantics
Affected files ...
.. //depot/projects/kmacy_sun4v/src/sys/kern/kern_sxu.c#4 edit
.. //depot/projects/kmacy_sun4v/src/sys/sys/sxu.h#3 edit
Differences ...
==== //depot/projects/kmacy_sun4v/src/sys/kern/kern_sxu.c#4 (text+ko) ====
@@ -110,6 +110,30 @@
lock_destroy(&sx->sxu_object);
}
+
+void
+_sxu_drain(struct sxu *sx, struct cv *cv_drain, const char *file, int line)
+{
+ mtx_lock(sx->sxu_lock);
+ KASSERT(sx->sxu_drain_cvp == NULL, ("sxu lock already being drained"));
+ KASSERT(sx->sx->sxu_xholder != curthread ("sxu draining against myself"));
+ WITNESS_CHECKORDER(&sx->sxu_object, LOP_NEWORDER, file, line);
+
+ sx->sxu_drain_cvp = cv_drain;
+ cv_wait(cv_drain, sx->sxu_lock);
+
+
+ /* Acquire an exclusive lock. */
+ sx->sxu_cnt--;
+ sx->sxu_xholder = curthread;
+ sx->sxu_drain_cvp = NULL;
+
+ LOCK_LOG_LOCK("SLOCK", &sx->sxu_object, 0, 0, file, line);
+ WITNESS_LOCK(&sx->sxu_object, 0, file, line);
+ mtx_unlock(sx->sxu_lock);
+}
+
+
int
_sxu_slock(struct sxu *sx, int timo, const char *file, int line)
{
@@ -132,8 +156,8 @@
if (sx->sxu_cnt < 0)
lock_profile_waitstart(&waittime);
while (sx->sxu_cnt < 0) {
+ lock_profile_obtain_lock_failed(&sx->sxu_object, &contested);
sx->sxu_shrd_wcnt++;
- lock_profile_obtain_lock_failed(&sx->sxu_object, &contested);
if (timo)
error = cv_timedwait(&sx->sxu_shrd_cv, sx->sxu_lock, timo);
else
@@ -273,11 +297,13 @@
if (sx->sxu_cnt == 0)
lock_profile_release_lock(&sx->sxu_object);
- if (sx->sxu_excl_wcnt > 0) {
- if (sx->sxu_cnt == 0)
- cv_signal(&sx->sxu_excl_cv);
- } else if (sx->sxu_shrd_wcnt > 0) /* XXX why would shrd_wcnt be > 0 if the holder is shared? */
+
+ if (sx->sxu_excl_wcnt > 0 && sx->sxu_cnt == 0)
+ cv_signal(&sx->sxu_excl_cv);
+ else if (sx->sxu_shrd_wcnt > 0) /* XXX why would shrd_wcnt be > 0 if the holder is shared? */
cv_broadcast(&sx->sxu_shrd_cv);
+ else if (sx->sxu_drain_cvp && (sx->sx_cnt == 0))
+ cv_signal(sx->sxu_drain_cvp);
LOCK_LOG_LOCK("SUNLOCK", &sx->sxu_object, 0, 0, file, line);
@@ -306,9 +332,10 @@
cv_broadcast(&sx->sxu_shrd_cv);
else if (sx->sxu_excl_wcnt > 0)
cv_signal(&sx->sxu_excl_cv);
+ else if (sx->sxu_drain_cvp)
+ cv_signal(sx->sxu_drain_cvp);
LOCK_LOG_LOCK("XUNLOCK", &sx->sxu_object, 0, 0, file, line);
-
mtx_unlock(sx->sxu_lock);
}
==== //depot/projects/kmacy_sun4v/src/sys/sys/sxu.h#3 (text+ko) ====
@@ -43,7 +43,7 @@
struct cv sxu_excl_cv; /* xlock waiters. */
int sxu_excl_wcnt; /* Number of xlock waiters. */
struct thread *sxu_xholder; /* Thread presently holding xlock. */
- struct cv sxu_drain_cv; /* drain waiter. */
+ struct cv *sxu_drain_cvp; /* pointer to drain waiter (if any). */
};
#ifdef _KERNEL
@@ -58,6 +58,8 @@
void _sxu_xunlock(struct sxu *sx, const char *file, int line);
int _sxu_try_upgrade(struct sxu *sx, const char *file, int line);
void _sxu_downgrade(struct sxu *sx, const char *file, int line);
+void _sxu_drain(struct sxu *sx, struct cv *cv_drain, const char *file, int line);
+
#ifdef INVARIANT_SUPPORT
void _sxu_assert(struct sxu *sxu, int what, const char *file, int line);
#endif
@@ -87,6 +89,8 @@
#define sxu_xunlock(sx) _sxu_xunlock((sx), LOCK_FILE, LOCK_LINE)
#define sxu_try_upgrade(sx) _sxu_try_upgrade((sx), LOCK_FILE, LOCK_LINE)
#define sxu_downgrade(sx) _sxu_downgrade((sx), LOCK_FILE, LOCK_LINE)
+#define sxu_drain(sx, cv) _sxu_drain((sx), (cv), LOCK_FILE, LOCK_LINE)
+
#define sxu_unlock(sx) do { \
if ((sx)->sx_cnt < 0) \
sxu_xunlock(sx); \
More information about the p4-projects
mailing list