PERFORCE change 100186 for review
Kip Macy
kmacy at FreeBSD.org
Wed Jun 28 06:12:34 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=100186
Change 100186 by kmacy at kmacy_storage:sun4v_work_sleepq on 2006/06/28 06:11:51
add LK_INTERLOCK and LK_CANRECURSE semantics - finally earning the name SX but Uglier
Affected files ...
.. //depot/projects/kmacy_sun4v/src/sys/kern/kern_sxu.c#5 edit
.. //depot/projects/kmacy_sun4v/src/sys/sys/sxu.h#4 edit
Differences ...
==== //depot/projects/kmacy_sun4v/src/sys/kern/kern_sxu.c#5 (text+ko) ====
@@ -135,7 +135,7 @@
int
-_sxu_slock(struct sxu *sx, int timo, const char *file, int line)
+_sxu_slock(struct sxu *sx, int timo, struct mtx *interlkp, const char *file, int line)
{
int contested, error;
@@ -145,6 +145,10 @@
error = 0;
mtx_lock(sx->sxu_lock);
+ if (interlkp) {
+ mxt_assert(m, MA_OWNED);
+ mtx_unlock(m);
+ }
KASSERT(sx->sxu_xholder != curthread,
("%s (%s): slock while xlock is held @ %s:%d\n", __func__,
sx->sxu_object.lo_name, file, line));
@@ -183,25 +187,30 @@
}
int
-_sxu_try_slock(struct sxu *sx, const char *file, int line)
+_sxu_try_slock(struct sxu *sx, struct mtx *interlkp, const char *file, int line)
{
-
+ int error;
mtx_lock(sx->sxu_lock);
+ if (interlkp) {
+ mxt_assert(interlkp, MA_OWNED);
+ mtx_unlock(interlkp);
+ }
if (sx->sxu_cnt >= 0) {
sx->sxu_cnt++;
LOCK_LOG_TRY("SLOCK", &sx->sxu_object, 0, 1, file, line);
WITNESS_LOCK(&sx->sxu_object, LOP_TRYLOCK, file, line);
- mtx_unlock(sx->sxu_lock);
- return (1);
+ error = 1;
+
} else {
LOCK_LOG_TRY("SLOCK", &sx->sxu_object, 0, 0, file, line);
- mtx_unlock(sx->sxu_lock);
- return (0);
+ error = 0;
}
+ mtx_unlock(sx->sxu_lock);
+ return (error);
}
int
-_sxu_xlock(struct sxu *sx, int timo, const char *file, int line)
+_sxu_xlock(struct sxu *sx, int timo, struct mtx *interlkp, int canrecurse, const char *file, int line)
{
int contested, error;
@@ -211,7 +220,10 @@
waittime= 0;
mtx_lock(sx->sxu_lock);
-
+ if (interlkp) {
+ mxt_assert(interlkp, MA_OWNED);
+ mtx_unlock(interlkp);
+ }
/*
* With sx locks, we're absolutely not permitted to recurse on
* xlocks, as it is fatal (deadlock). Normally, recursion is handled
@@ -219,15 +231,20 @@
* xlock while in here, we consider it API abuse and put it under
* INVARIANTS.
*/
- KASSERT(sx->sxu_xholder != curthread,
- ("%s (%s): xlock already held @ %s:%d", __func__,
- sx->sxu_object.lo_name, file, line));
+ if (!canrecurse) {
+ KASSERT(sx->sxu_xholder != curthread,
+ ("%s (%s): xlock already held @ %s:%d", __func__,
+ sx->sxu_object.lo_name, file, line));
+
+ } else if (canrecurse && sx->sxu_xholder == curthread) {
+ sx->sxu_cnt--;
+ goto done;
+ }
WITNESS_CHECKORDER(&sx->sxu_object, LOP_NEWORDER | LOP_EXCLUSIVE, file,
- line);
+ line);
+ /* Loop in case we lose the race for lock acquisition. */
- /* Loop in case we lose the race for lock acquisition. */
- if (sx->sxu_cnt)
- lock_profile_waitstart(&waittime);
+ lock_profile_waitstart(&waittime);
while (sx->sxu_cnt != 0) {
sx->sxu_excl_wcnt++;
lock_profile_obtain_lock_failed(&sx->sxu_object, &contested);
@@ -238,7 +255,7 @@
sx->sxu_excl_wcnt--;
if (error)
- goto fail;
+ goto done;
}
MPASS(sx->sxu_cnt == 0);
@@ -251,29 +268,38 @@
LOCK_LOG_LOCK("XLOCK", &sx->sxu_object, 0, 0, file, line);
WITNESS_LOCK(&sx->sxu_object, LOP_EXCLUSIVE, file, line);
- fail:
+ done:
mtx_unlock(sx->sxu_lock);
return (error);
}
int
-_sxu_try_xlock(struct sxu *sx, const char *file, int line)
+_sxu_try_xlock(struct sxu *sx, struct mtx *interlkp, int canrecurse, const char *file, int line)
{
+ int error;
mtx_lock(sx->sxu_lock);
- if (sx->sxu_cnt == 0) {
+ if (interlkp) {
+ mxt_assert(interlkp, MA_OWNED);
+ mtx_unlock(interlkp);
+ }
+ KASSERT((sx->sxu_cnt >= 0) || canrecurse, ("recursing on non-recursable lock"));
+ if (sx->sxu_cnt <= 0) {
sx->sxu_cnt--;
sx->sxu_xholder = curthread;
- LOCK_LOG_TRY("XLOCK", &sx->sxu_object, 0, 1, file, line);
- WITNESS_LOCK(&sx->sxu_object, LOP_EXCLUSIVE | LOP_TRYLOCK, file,
- line);
- mtx_unlock(sx->sxu_lock);
- return (1);
+ if (!canrecurse) {
+ LOCK_LOG_TRY("XLOCK", &sx->sxu_object, 0, 1, file, line);
+ WITNESS_LOCK(&sx->sxu_object, LOP_EXCLUSIVE | LOP_TRYLOCK, file,
+ line);
+ }
+ error = 1;
} else {
LOCK_LOG_TRY("XLOCK", &sx->sxu_object, 0, 0, file, line);
- mtx_unlock(sx->sxu_lock);
- return (0);
+ error = 0;
}
+ mtx_unlock(sx->sxu_lock);
+
+ return (error);
}
void
@@ -322,6 +348,9 @@
/* Release. */
sx->sxu_cnt++;
+ if (sx->sxu_cnt < 0)
+ goto done;
+
sx->sxu_xholder = NULL;
lock_profile_release_lock(&sx->sxu_object);
@@ -336,6 +365,7 @@
cv_signal(sx->sxu_drain_cvp);
LOCK_LOG_LOCK("XUNLOCK", &sx->sxu_object, 0, 0, file, line);
+ done:
mtx_unlock(sx->sxu_lock);
}
==== //depot/projects/kmacy_sun4v/src/sys/sys/sxu.h#4 (text+ko) ====
@@ -50,10 +50,10 @@
void sxu_sysinit(void *arg);
void sxu_init(struct sxu *sx, const char *description);
void sxu_destroy(struct sxu *sx);
-void _sxu_slock(struct sxu *sx, int timo, const char *file, int line);
-void _sxu_xlock(struct sxu *sx, int timo, const char *file, int line);
-int _sxu_try_slock(struct sxu *sx, const char *file, int line);
-int _sxu_try_xlock(struct sxu *sx, const char *file, int line);
+void _sxu_slock(struct sxu *sx, int timo, struct mtx *interlkp, const char *file, int line);
+void _sxu_xlock(struct sxu *sx, int timo, int interlkp, int canrecurse, const char *file, int line);
+int _sxu_try_slock(struct sxu *sx, mtx *interlkp, const char *file, int line);
+int _sxu_try_xlock(struct sxu *sx, struct mtx *interlkp, int canrecurse, const char *file, int line);
void _sxu_sunlock(struct sxu *sx, const char *file, int line);
void _sxu_xunlock(struct sxu *sx, const char *file, int line);
int _sxu_try_upgrade(struct sxu *sx, const char *file, int line);
@@ -79,18 +79,33 @@
SYSUNINIT(name##_sxu_sysuninit, SI_SUB_LOCK, SI_ORDER_MIDDLE, \
sxu_destroy, (sxa))
-#define sxu_slock(sx) _sxu_slock((sx), (0), LOCK_FILE, LOCK_LINE)
-#define sxu_xlock(sx) _sxu_xlock((sx), (0), LOCK_FILE, LOCK_LINE)
-#define sxu_slock_timedwait(sx, timo) _sxu_slock((sx), (timo), LOCK_FILE, LOCK_LINE)
-#define sxu_xlock_timedwait(sx, timo) _sxu_xlock((sx), (timo), LOCK_FILE, LOCK_LINE)
-#define sxu_try_slock(sx) _sxu_try_slock((sx), LOCK_FILE, LOCK_LINE)
-#define sxu_try_xlock(sx) _sxu_try_xlock((sx), LOCK_FILE, LOCK_LINE)
+#define sxu_slock(sx) \
+ _sxu_slock((sx), (0), NULL, LOCK_FILE, LOCK_LINE)
+#define sxu_xlock(sx, canrecurse) \
+ _sxu_xlock((sx), (0), NULL, (canrecurse), LOCK_FILE, LOCK_LINE)
+#define sxu_slock_interlocked(sx, interlkp) \
+ _sxu_slock((sx), (0), interlkp, LOCK_FILE, LOCK_LINE)
+#define sxu_xlock_interlocked(sx, interlkp, canrecurse) \
+ _sxu_xlock((sx), (0), interlkp, LOCK_FILE, LOCK_LINE)
+#define sxu_try_slock(sx) \
+ _sxu_try_slock((sx), (NULL), LOCK_FILE, LOCK_LINE)
+#define sxu_try_xlock(sx, int canrecurse) \
+ _sxu_try_xlock((sx), (NULL), (canrecurse), LOCK_FILE, LOCK_LINE)
+#define sxu_try_slock_interlocked(sx, interlkp) \
+ _sxu_try_slock((sx), (interlkp), LOCK_FILE, LOCK_LINE)
+#define sxu_try_xlock_interlocked(sx, interlkp, int canrecurse) \
+ _sxu_try_xlock((sx), (interlkp), (canrecurse), LOCK_FILE, LOCK_LINE)
+
+#define sxu_xlock_interlock_timedwait(sx, timo, interlkp, canrecurse) \
+ _sxu_xlock((sx), (timo), (interlkp), (canrecurse), LOCK_FILE, LOCK_LINE)
+
#define sxu_sunlock(sx) _sxu_sunlock((sx), LOCK_FILE, LOCK_LINE)
#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