summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1998-03-07 19:25:34 +0000
committerdyson <dyson@FreeBSD.org>1998-03-07 19:25:34 +0000
commitf5ff9feb6766e0b73f72b7621d90fbfe4954fa99 (patch)
tree69755379d74fac02f6dfdcc02e48a6ef6b38391f /sys
parent0627b813cd0dc0a1fb6512e804559abc466e29be (diff)
downloadFreeBSD-src-f5ff9feb6766e0b73f72b7621d90fbfe4954fa99.zip
FreeBSD-src-f5ff9feb6766e0b73f72b7621d90fbfe4954fa99.tar.gz
Some kern_lock code improvements. Add missing wakeup, and enable
disabling some diagnostics when memory or speed is at a premium.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_lock.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index 97063b5..d3d0df0 100644
--- a/sys/kern/kern_lock.c
+++ b/sys/kern/kern_lock.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* @(#)kern_lock.c 8.18 (Berkeley) 5/21/95
- * $Id: kern_lock.c,v 1.16 1998/02/06 12:13:23 eivind Exp $
+ * $Id: kern_lock.c,v 1.17 1998/02/11 00:05:26 eivind Exp $
*/
#include "opt_lint.h"
@@ -92,9 +92,15 @@ shareunlock(struct lock *lkp, int decr) {
#endif
#endif
- lkp->lk_sharecount -= decr;
- if (lkp->lk_sharecount == 0)
+ if (lkp->lk_sharecount == decr) {
lkp->lk_flags &= ~LK_SHARE_NONZERO;
+ if (lkp->lk_flags & (LK_WANT_UPGRADE | LK_WANT_EXCL)) {
+ wakeup(lkp);
+ }
+ lkp->lk_sharecount = 0;
+ } else {
+ lkp->lk_sharecount -= decr;
+ }
}
/*
@@ -125,7 +131,7 @@ apause(struct lock *lkp, int flags) {
static int
acquire(struct lock *lkp, int extflags, int wanted) {
- int error;
+ int s, error;
if ((extflags & LK_NOWAIT) && (lkp->lk_flags & wanted)) {
return EBUSY;
@@ -137,21 +143,29 @@ acquire(struct lock *lkp, int extflags, int wanted) {
return 0;
}
+ s = splhigh();
while ((lkp->lk_flags & wanted) != 0) {
lkp->lk_flags |= LK_WAIT_NONZERO;
lkp->lk_waitcount++;
simple_unlock(&lkp->lk_interlock);
error = tsleep(lkp, lkp->lk_prio, lkp->lk_wmesg, lkp->lk_timo);
simple_lock(&lkp->lk_interlock);
- lkp->lk_waitcount--;
- if (lkp->lk_waitcount == 0)
+ if (lkp->lk_waitcount == 1) {
lkp->lk_flags &= ~LK_WAIT_NONZERO;
- if (error)
+ lkp->lk_waitcount = 0;
+ } else {
+ lkp->lk_waitcount--;
+ }
+ if (error) {
+ splx(s);
return error;
+ }
if (extflags & LK_SLEEPFAIL) {
+ splx(s);
return ENOLCK;
}
}
+ splx(s);
return 0;
}
@@ -206,8 +220,10 @@ lockmgr(lkp, flags, interlkp, p)
/* fall into downgrade */
case LK_DOWNGRADE:
+#if !defined(MAX_PERF)
if (lkp->lk_lockholder != pid || lkp->lk_exclusivecount == 0)
panic("lockmgr: not holding exclusive lock");
+#endif
sharelock(lkp, lkp->lk_exclusivecount);
lkp->lk_exclusivecount = 0;
lkp->lk_flags &= ~LK_HAVE_EXCL;
@@ -239,8 +255,10 @@ lockmgr(lkp, flags, interlkp, p)
* after the upgrade). If we return an error, the file
* will always be unlocked.
*/
+#if !defined(MAX_PERF)
if ((lkp->lk_lockholder == pid) || (lkp->lk_sharecount <= 0))
panic("lockmgr: upgrade exclusive lock");
+#endif
shareunlock(lkp, 1);
COUNT(p, -1);
/*
@@ -259,14 +277,17 @@ lockmgr(lkp, flags, interlkp, p)
* drop to zero, then take exclusive lock.
*/
lkp->lk_flags |= LK_WANT_UPGRADE;
- error = acquire(lkp, extflags , LK_SHARE_NONZERO);
+ error = acquire(lkp, extflags, LK_SHARE_NONZERO);
lkp->lk_flags &= ~LK_WANT_UPGRADE;
+
if (error)
break;
lkp->lk_flags |= LK_HAVE_EXCL;
lkp->lk_lockholder = pid;
+#if !defined(MAX_PERF)
if (lkp->lk_exclusivecount != 0)
panic("lockmgr: non-zero exclusive count");
+#endif
lkp->lk_exclusivecount = 1;
COUNT(p, 1);
break;
@@ -286,8 +307,10 @@ lockmgr(lkp, flags, interlkp, p)
/*
* Recursive lock.
*/
+#if !defined(MAX_PERF)
if ((extflags & LK_CANRECURSE) == 0)
panic("lockmgr: locking against myself");
+#endif
lkp->lk_exclusivecount++;
COUNT(p, 1);
break;
@@ -316,23 +339,29 @@ lockmgr(lkp, flags, interlkp, p)
break;
lkp->lk_flags |= LK_HAVE_EXCL;
lkp->lk_lockholder = pid;
+#if !defined(MAX_PERF)
if (lkp->lk_exclusivecount != 0)
panic("lockmgr: non-zero exclusive count");
+#endif
lkp->lk_exclusivecount = 1;
COUNT(p, 1);
break;
case LK_RELEASE:
if (lkp->lk_exclusivecount != 0) {
+#if !defined(MAX_PERF)
if (pid != lkp->lk_lockholder)
panic("lockmgr: pid %d, not %s %d unlocking",
pid, "exclusive lock holder",
lkp->lk_lockholder);
- lkp->lk_exclusivecount--;
+#endif
COUNT(p, -1);
- if (lkp->lk_exclusivecount == 0) {
+ if (lkp->lk_exclusivecount == 1) {
lkp->lk_flags &= ~LK_HAVE_EXCL;
lkp->lk_lockholder = LK_NOPROC;
+ lkp->lk_exclusivecount = 0;
+ } else {
+ lkp->lk_exclusivecount--;
}
} else if (lkp->lk_flags & LK_SHARE_NONZERO) {
shareunlock(lkp, 1);
@@ -349,8 +378,10 @@ lockmgr(lkp, flags, interlkp, p)
* check for holding a shared lock, but at least we can
* check for an exclusive one.
*/
+#if !defined(MAX_PERF)
if (lkp->lk_lockholder == pid)
panic("lockmgr: draining against myself");
+#endif
error = acquiredrain(lkp, extflags);
if (error)
@@ -362,9 +393,11 @@ lockmgr(lkp, flags, interlkp, p)
break;
default:
+#if !defined(MAX_PERF)
simple_unlock(&lkp->lk_interlock);
panic("lockmgr: unknown locktype request %d",
flags & LK_TYPE_MASK);
+#endif
/* NOTREACHED */
}
if ((lkp->lk_flags & LK_WAITDRAIN) &&
OpenPOWER on IntegriCloud