summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_lock.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-09-21 04:24:27 +0000
committerdyson <dyson@FreeBSD.org>1997-09-21 04:24:27 +0000
commite64b1984f97c6d987d7d36b61a3afe5028a08312 (patch)
tree325bcf17de3aad0383fb86548872026a7c3d2599 /sys/kern/kern_lock.c
parent1419fcb42b4e1e5a73f4574739f4c232fde357e2 (diff)
downloadFreeBSD-src-e64b1984f97c6d987d7d36b61a3afe5028a08312.zip
FreeBSD-src-e64b1984f97c6d987d7d36b61a3afe5028a08312.tar.gz
Change the M_NAMEI allocations to use the zone allocator. This change
plus the previous changes to use the zone allocator decrease the useage of malloc by half. The Zone allocator will be upgradeable to be able to use per CPU-pools, and has more intelligent usage of SPLs. Additionally, it has reasonable stats gathering capabilities, while making most calls inline.
Diffstat (limited to 'sys/kern/kern_lock.c')
-rw-r--r--sys/kern/kern_lock.c162
1 files changed, 85 insertions, 77 deletions
diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c
index d119c57..ff1b252 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.10 1997/08/19 00:27:07 dyson Exp $
+ * $Id: kern_lock.c,v 1.11 1997/08/22 07:16:46 phk Exp $
*/
#include <sys/param.h>
@@ -70,7 +70,12 @@
#define LOCK_INLINE inline
#endif
+#define LK_ALL (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | \
+ LK_SHARE_NONZERO | LK_WAIT_NONZERO)
+
static int acquire(struct lock *lkp, int extflags, int wanted);
+static int apause(struct lock *lkp, int flags);
+static int acquiredrain(struct lock *lkp, int extflags) ;
static LOCK_INLINE void
sharelock(struct lock *lkp, int incr) {
@@ -94,6 +99,11 @@ shareunlock(struct lock *lkp, int decr) {
lkp->lk_flags &= ~LK_SHARE_NONZERO;
}
+/*
+ * This is the waitloop optimization, and note for this to work
+ * simple_lock and simple_unlock should be subroutines to avoid
+ * optimization troubles.
+ */
static int
apause(struct lock *lkp, int flags) {
int lock_wait;
@@ -115,7 +125,6 @@ apause(struct lock *lkp, int flags) {
return 1;
}
-
static int
acquire(struct lock *lkp, int extflags, int wanted) {
int error;
@@ -125,9 +134,11 @@ acquire(struct lock *lkp, int extflags, int wanted) {
return EBUSY;
}
- error = apause(lkp, wanted);
- if (error == 0)
- return 0;
+ if (((lkp->lk_flags | extflags) & LK_NOPAUSE) == 0) {
+ error = apause(lkp, wanted);
+ if (error == 0)
+ return 0;
+ }
while ((lkp->lk_flags & wanted) != 0) {
lkp->lk_flags |= LK_WAIT_NONZERO;
@@ -147,78 +158,6 @@ acquire(struct lock *lkp, int extflags, int wanted) {
return 0;
}
-#define LK_ALL (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | \
- LK_SHARE_NONZERO | LK_WAIT_NONZERO)
-
-static int
-acquiredrain(struct lock *lkp, int extflags) {
- int error;
- int lock_wait;
-
- if ((extflags & LK_NOWAIT) && (lkp->lk_flags & LK_ALL)) {
- return EBUSY;
- }
-
- error = apause(lkp, LK_ALL);
- if (error == 0)
- return 0;
-
- while (lkp->lk_flags & LK_ALL) {
- lkp->lk_flags |= LK_WAITDRAIN;
- simple_unlock(&lkp->lk_interlock);
- error = tsleep(&lkp->lk_flags, lkp->lk_prio,
- lkp->lk_wmesg, lkp->lk_timo);
- simple_lock(&lkp->lk_interlock);
- if (error)
- return error;
- if (extflags & LK_SLEEPFAIL) {
- return ENOLCK;
- }
- }
- return 0;
-}
-
-/*
- * Initialize a lock; required before use.
- */
-void
-lockinit(lkp, prio, wmesg, timo, flags)
- struct lock *lkp;
- int prio;
- char *wmesg;
- int timo;
- int flags;
-{
-
- simple_lock_init(&lkp->lk_interlock);
- lkp->lk_flags = (flags & LK_EXTFLG_MASK);
- lkp->lk_sharecount = 0;
- lkp->lk_waitcount = 0;
- lkp->lk_exclusivecount = 0;
- lkp->lk_prio = prio;
- lkp->lk_wmesg = wmesg;
- lkp->lk_timo = timo;
- lkp->lk_lockholder = LK_NOPROC;
-}
-
-/*
- * Determine the status of a lock.
- */
-int
-lockstatus(lkp)
- struct lock *lkp;
-{
- int lock_type = 0;
-
- simple_lock(&lkp->lk_interlock);
- if (lkp->lk_exclusivecount != 0)
- lock_type = LK_EXCLUSIVE;
- else if (lkp->lk_sharecount != 0)
- lock_type = LK_SHARED;
- simple_unlock(&lkp->lk_interlock);
- return (lock_type);
-}
-
/*
* Set, change, or release a lock.
*
@@ -441,6 +380,75 @@ lockmgr(lkp, flags, interlkp, p)
return (error);
}
+static int
+acquiredrain(struct lock *lkp, int extflags) {
+ int error;
+ int lock_wait;
+
+ if ((extflags & LK_NOWAIT) && (lkp->lk_flags & LK_ALL)) {
+ return EBUSY;
+ }
+
+ error = apause(lkp, LK_ALL);
+ if (error == 0)
+ return 0;
+
+ while (lkp->lk_flags & LK_ALL) {
+ lkp->lk_flags |= LK_WAITDRAIN;
+ simple_unlock(&lkp->lk_interlock);
+ error = tsleep(&lkp->lk_flags, lkp->lk_prio,
+ lkp->lk_wmesg, lkp->lk_timo);
+ simple_lock(&lkp->lk_interlock);
+ if (error)
+ return error;
+ if (extflags & LK_SLEEPFAIL) {
+ return ENOLCK;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Initialize a lock; required before use.
+ */
+void
+lockinit(lkp, prio, wmesg, timo, flags)
+ struct lock *lkp;
+ int prio;
+ char *wmesg;
+ int timo;
+ int flags;
+{
+
+ simple_lock_init(&lkp->lk_interlock);
+ lkp->lk_flags = (flags & LK_EXTFLG_MASK);
+ lkp->lk_sharecount = 0;
+ lkp->lk_waitcount = 0;
+ lkp->lk_exclusivecount = 0;
+ lkp->lk_prio = prio;
+ lkp->lk_wmesg = wmesg;
+ lkp->lk_timo = timo;
+ lkp->lk_lockholder = LK_NOPROC;
+}
+
+/*
+ * Determine the status of a lock.
+ */
+int
+lockstatus(lkp)
+ struct lock *lkp;
+{
+ int lock_type = 0;
+
+ simple_lock(&lkp->lk_interlock);
+ if (lkp->lk_exclusivecount != 0)
+ lock_type = LK_EXCLUSIVE;
+ else if (lkp->lk_sharecount != 0)
+ lock_type = LK_SHARED;
+ simple_unlock(&lkp->lk_interlock);
+ return (lock_type);
+}
+
/*
* Print out information about state of a lock. Used by VOP_PRINT
* routines to display status about contained locks.
OpenPOWER on IntegriCloud