Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Fix a thinko in draining of spin locks: bump waitcount i...
details: https://anonhg.NetBSD.org/src/rev/d56b1f91189e
branches: trunk
changeset: 474988:d56b1f91189e
user: thorpej <thorpej%NetBSD.org@localhost>
date: Wed Jul 28 19:29:39 1999 +0000
description:
Fix a thinko in draining of spin locks: bump waitcount in the spin case,
too. Remove some needless code duplication by adding a "drain" argument
to the ACQUIRE() macro (compiler can [and does] optimize the constant
conditional).
diffstat:
sys/kern/kern_lock.c | 84 +++++++++++++++++++++++++--------------------------
sys/sys/lock.h | 7 +---
2 files changed, 43 insertions(+), 48 deletions(-)
diffs (220 lines):
diff -r accf04855fb5 -r d56b1f91189e sys/kern/kern_lock.c
--- a/sys/kern/kern_lock.c Wed Jul 28 17:13:54 1999 +0000
+++ b/sys/kern/kern_lock.c Wed Jul 28 19:29:39 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_lock.c,v 1.22 1999/07/28 01:59:46 mellon Exp $ */
+/* $NetBSD: kern_lock.c,v 1.23 1999/07/28 19:29:39 thorpej Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -117,10 +117,12 @@
/*
* Acquire a resource.
*/
-#define ACQUIRE(lkp, error, extflags, wanted) \
+#define ACQUIRE(lkp, error, extflags, drain, wanted) \
if ((extflags) & LK_SPIN) { \
int interlocked; \
\
+ if ((drain) == 0) \
+ (lkp)->lk_waitcount++; \
for (interlocked = 1;;) { \
if (wanted) { \
if (interlocked) { \
@@ -134,16 +136,24 @@
interlocked = 1; \
} \
} \
+ if ((drain) == 0) \
+ (lkp)->lk_waitcount--; \
KASSERT((wanted) == 0); \
error = 0; /* sanity */ \
} else { \
for (error = 0; wanted; ) { \
- (lkp)->lk_waitcount++; \
+ if ((drain)) \
+ (lkp)->lk_flags |= LK_WAITDRAIN; \
+ else \
+ (lkp)->lk_waitcount++; \
simple_unlock(&(lkp)->lk_interlock); \
- error = tsleep((void *)lkp, (lkp)->lk_prio, \
+ /* XXX Cast away volatile. */ \
+ error = tsleep((drain) ? &(lkp)->lk_flags : \
+ (void *)(lkp), (lkp)->lk_prio, \
(lkp)->lk_wmesg, (lkp)->lk_timo); \
simple_lock(&(lkp)->lk_interlock); \
- (lkp)->lk_waitcount--; \
+ if ((drain) == 0) \
+ (lkp)->lk_waitcount--; \
if (error) \
break; \
if ((extflags) & LK_SLEEPFAIL) { \
@@ -165,6 +175,14 @@
(((lkp)->lk_flags & LK_SPIN) != 0 ? \
((lkp)->lk_cpu == (cpu_id)) : ((lkp)->lk_lockholder == (pid)))
+#define WAKEUP_WAITER(lkp) \
+do { \
+ if (((lkp)->lk_flags & LK_SPIN) == 0 && (lkp)->lk_waitcount) { \
+ /* XXX Cast away volatile. */ \
+ wakeup_one((void *)(lkp)); \
+ } \
+} while (0)
+
#if defined(LOCKDEBUG) /* { */
#if defined(MULTIPROCESSOR) /* { */
struct simplelock spinlock_list_slock = SIMPLELOCK_INITIALIZER;
@@ -341,7 +359,7 @@
/*
* Wait for exclusive locks and upgrades to clear.
*/
- ACQUIRE(lkp, error, extflags, lkp->lk_flags &
+ ACQUIRE(lkp, error, extflags, 0, lkp->lk_flags &
(LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE));
if (error)
break;
@@ -367,8 +385,7 @@
lkp->lk_flags &= ~LK_HAVE_EXCL;
SETHOLDER(lkp, LK_NOPROC, LK_NOCPU);
DONTHAVEIT(lkp);
- if (lkp->lk_waitcount)
- wakeup_one((void *)lkp);
+ WAKEUP_WAITER(lkp);
break;
case LK_EXCLUPGRADE:
@@ -414,7 +431,7 @@
* drop to zero, then take exclusive lock.
*/
lkp->lk_flags |= LK_WANT_UPGRADE;
- ACQUIRE(lkp, error, extflags, lkp->lk_sharecount);
+ ACQUIRE(lkp, error, extflags, 0, lkp->lk_sharecount);
lkp->lk_flags &= ~LK_WANT_UPGRADE;
if (error)
break;
@@ -434,8 +451,8 @@
* lock, awaken upgrade requestor if we are the last shared
* lock, then request an exclusive lock.
*/
- if (lkp->lk_sharecount == 0 && lkp->lk_waitcount)
- wakeup_one((void *)lkp);
+ if (lkp->lk_sharecount == 0)
+ WAKEUP_WAITER(lkp);
/* fall into exclusive request */
case LK_EXCLUSIVE:
@@ -470,7 +487,7 @@
/*
* Try to acquire the want_exclusive flag.
*/
- ACQUIRE(lkp, error, extflags, lkp->lk_flags &
+ ACQUIRE(lkp, error, extflags, 0, lkp->lk_flags &
(LK_HAVE_EXCL | LK_WANT_EXCL));
if (error)
break;
@@ -478,7 +495,7 @@
/*
* Wait for shared locks and upgrades to finish.
*/
- ACQUIRE(lkp, error, extflags, lkp->lk_sharecount != 0 ||
+ ACQUIRE(lkp, error, extflags, 0, lkp->lk_sharecount != 0 ||
(lkp->lk_flags & LK_WANT_UPGRADE));
lkp->lk_flags &= ~LK_WANT_EXCL;
if (error)
@@ -521,8 +538,7 @@
lkp->lk_sharecount--;
COUNT(lkp, p, cpu_id, -1);
}
- if (lkp->lk_waitcount)
- wakeup_one((void *)lkp);
+ WAKEUP_WAITER(lkp);
break;
case LK_DRAIN:
@@ -543,32 +559,13 @@
error = EBUSY;
break;
}
- if (lkp->lk_flags & LK_SPIN) {
- ACQUIRE(lkp, error, extflags,
- ((lkp->lk_flags &
- (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) ||
- lkp->lk_sharecount != 0 ||
- lkp->lk_waitcount != 0));
- } else {
- /*
- * This is just a special cause of the sleep case
- * in ACQUIRE(). We set WANTDRAIN instead of
- * incrementing waitcount.
- */
- for (error = 0; ((lkp->lk_flags &
- (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) ||
- lkp->lk_sharecount != 0 ||
- lkp->lk_waitcount != 0); ) {
- lkp->lk_flags |= LK_WAITDRAIN;
- simple_unlock(&lkp->lk_interlock);
- if ((error = tsleep((void *)&lkp->lk_flags,
- lkp->lk_prio, lkp->lk_wmesg, lkp->lk_timo)))
- return (error);
- if ((extflags) & LK_SLEEPFAIL)
- return (ENOLCK);
- simple_lock(&lkp->lk_interlock);
- }
- }
+ ACQUIRE(lkp, error, extflags, 1,
+ ((lkp->lk_flags &
+ (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) ||
+ lkp->lk_sharecount != 0 ||
+ lkp->lk_waitcount != 0));
+ if (error)
+ break;
lkp->lk_flags |= LK_DRAINING | LK_HAVE_EXCL;
SETHOLDER(lkp, pid, cpu_id);
HAVEIT(lkp);
@@ -585,8 +582,9 @@
flags & LK_TYPE_MASK);
/* NOTREACHED */
}
- if ((lkp->lk_flags & LK_WAITDRAIN) && ((lkp->lk_flags &
- (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) == 0 &&
+ if ((lkp->lk_flags & (LK_WAITDRAIN|LK_SPIN)) == LK_WAITDRAIN &&
+ ((lkp->lk_flags &
+ (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) == 0 &&
lkp->lk_sharecount == 0 && lkp->lk_waitcount == 0)) {
lkp->lk_flags &= ~LK_WAITDRAIN;
wakeup_one((void *)&lkp->lk_flags);
diff -r accf04855fb5 -r d56b1f91189e sys/sys/lock.h
--- a/sys/sys/lock.h Wed Jul 28 17:13:54 1999 +0000
+++ b/sys/sys/lock.h Wed Jul 28 19:29:39 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: lock.h,v 1.21 1999/07/27 23:45:13 thorpej Exp $ */
+/* $NetBSD: lock.h,v 1.22 1999/07/28 19:29:39 thorpej Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -140,6 +140,7 @@
int lk_sharecount; /* # of accepted shared locks */
short lk_exclusivecount; /* # of recursive exclusive locks */
short lk_recurselevel; /* lvl above which recursion ok */
+ int lk_waitcount; /* # of sleepers/spinners */
/*
* This is the sleep message for sleep locks, and a simple name
@@ -152,9 +153,6 @@
/* pid of exclusive lock holder */
pid_t lk_sleep_lockholder;
- /* # of processes sleeping for lock */
- int lk_sleep_waitcount;
-
/* priority at which to sleep */
int lk_sleep_prio;
@@ -171,7 +169,6 @@
} lk_un;
#define lk_lockholder lk_un.lk_un_sleep.lk_sleep_lockholder
-#define lk_waitcount lk_un.lk_un_sleep.lk_sleep_waitcount
#define lk_prio lk_un.lk_un_sleep.lk_sleep_prio
#define lk_timo lk_un.lk_un_sleep.lk_sleep_timo
Home |
Main Index |
Thread Index |
Old Index