Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Jun 2006 06:12:32 GMT
From:      Kip Macy <kmacy@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 100186 for review
Message-ID:  <200606280612.k5S6CWch060931@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=100186

Change 100186 by kmacy@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);					\



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606280612.k5S6CWch060931>