Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys turn ACQUIRE macro into a function by introducing new in...



details:   https://anonhg.NetBSD.org/src/rev/6799d0c7bb6b
branches:  trunk
changeset: 555608:6799d0c7bb6b
user:      yamt <yamt%NetBSD.org@localhost>
date:      Sun Nov 23 08:57:16 2003 +0000

description:
turn ACQUIRE macro into a function by introducing new internal
flags, LK_SHARE_NONZERO and LK_WAIT_NONZERO.  from FreeBSD.

diffstat:

 sys/kern/kern_lock.c |  176 +++++++++++++++++++++++++++++---------------------
 sys/sys/lock.h       |    7 +-
 2 files changed, 107 insertions(+), 76 deletions(-)

diffs (truncated from 333 to 300 lines):

diff -r acbc37dee79f -r 6799d0c7bb6b sys/kern/kern_lock.c
--- a/sys/kern/kern_lock.c      Sun Nov 23 08:54:57 2003 +0000
+++ b/sys/kern/kern_lock.c      Sun Nov 23 08:57:16 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_lock.c,v 1.72 2003/08/07 16:31:46 agc Exp $       */
+/*     $NetBSD: kern_lock.c,v 1.73 2003/11/23 08:57:17 yamt Exp $      */
 
 /*-
  * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.72 2003/08/07 16:31:46 agc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lock.c,v 1.73 2003/11/23 08:57:17 yamt Exp $");
 
 #include "opt_multiprocessor.h"
 #include "opt_lockdebug.h"
@@ -100,6 +100,8 @@
 void   lock_printf(const char *fmt, ...)
     __attribute__((__format__(__printf__,1,2)));
 
+static int acquire(__volatile struct lock *, int, int, int);
+
 int    lock_debug_syslog = 0;  /* defaults to printf, but can be patched */
 
 #ifdef DDB
@@ -206,56 +208,75 @@
 /*
  * Acquire a resource.
  */
-#define ACQUIRE(lkp, error, extflags, drain, wanted)                   \
-       if ((extflags) & LK_SPIN) {                                     \
-               int interlocked;                                        \
-               SPINLOCK_SPINCHECK_DECL;                                \
-                                                                       \
-               if ((drain) == 0)                                       \
-                       (lkp)->lk_waitcount++;                          \
-               for (interlocked = 1;;) {                               \
-                       SPINLOCK_SPINCHECK;                             \
-                       if (wanted) {                                   \
-                               if (interlocked) {                      \
-                                       INTERLOCK_RELEASE((lkp),        \
-                                           LK_SPIN, s);                \
-                                       interlocked = 0;                \
-                               }                                       \
-                               SPINLOCK_SPIN_HOOK;                     \
-                       } else if (interlocked) {                       \
-                               break;                                  \
-                       } else {                                        \
-                               INTERLOCK_ACQUIRE((lkp), LK_SPIN, s);   \
-                               interlocked = 1;                        \
-                       }                                               \
-               }                                                       \
-               if ((drain) == 0)                                       \
-                       (lkp)->lk_waitcount--;                          \
-               KASSERT((wanted) == 0);                                 \
-               error = 0;      /* sanity */                            \
-       } else {                                                        \
-               for (error = 0; wanted; ) {                             \
-                       if ((drain))                                    \
-                               (lkp)->lk_flags |= LK_WAITDRAIN;        \
-                       else                                            \
-                               (lkp)->lk_waitcount++;                  \
-                       /* XXX Cast away volatile. */                   \
-                       error = ltsleep((drain) ?                       \
-                           (void *)&(lkp)->lk_flags :                  \
-                           (void *)(lkp), (lkp)->lk_prio,              \
-                           (lkp)->lk_wmesg, (lkp)->lk_timo,            \
-                           &(lkp)->lk_interlock);                      \
-                       if ((drain) == 0)                               \
-                               (lkp)->lk_waitcount--;                  \
-                       if (error)                                      \
-                               break;                                  \
-                       if ((extflags) & LK_SLEEPFAIL) {                \
-                               error = ENOLCK;                         \
-                               break;                                  \
-                       }                                               \
-               }                                                       \
+static int
+acquire(__volatile struct lock *lkp, int extflags, int drain, int wanted)
+{
+       int error;
+
+       KASSERT(drain || (wanted & LK_WAIT_NONZERO) == 0);
+
+       if (extflags & LK_SPIN) {
+               int s = 0; /* XXX gcc */
+               int interlocked;
+
+               SPINLOCK_SPINCHECK_DECL;
+
+               if (!drain) {
+                       lkp->lk_waitcount++;
+                       lkp->lk_flags |= LK_WAIT_NONZERO;
+               }
+               for (interlocked = 1;;) {
+                       SPINLOCK_SPINCHECK;
+                       if ((lkp->lk_flags & wanted) != 0) {
+                               if (interlocked) {
+                                       INTERLOCK_RELEASE(lkp, LK_SPIN, s);
+                                       interlocked = 0;
+                               }
+                               SPINLOCK_SPIN_HOOK;
+                       } else if (interlocked) {
+                               break;
+                       } else {
+                               INTERLOCK_ACQUIRE(lkp, LK_SPIN, s);
+                               interlocked = 1;
+                       }
+               }
+               if (!drain) {
+                       lkp->lk_waitcount--;
+                       if (lkp->lk_waitcount == 0)
+                               lkp->lk_flags &= ~LK_WAIT_NONZERO;
+               }
+               KASSERT((lkp->lk_flags & wanted) == 0);
+               error = 0;      /* sanity */
+       } else {
+               for (error = 0; (lkp->lk_flags & wanted) != 0; ) {
+                       if (drain)
+                               lkp->lk_flags |= LK_WAITDRAIN;
+                       else {
+                               lkp->lk_waitcount++;
+                               lkp->lk_flags |= LK_WAIT_NONZERO;
+                       }
+                       /* XXX Cast away volatile. */
+                       error = ltsleep(drain ?
+                           (void *)&lkp->lk_flags :
+                           (void *)lkp, lkp->lk_prio,
+                           lkp->lk_wmesg, lkp->lk_timo, &lkp->lk_interlock);
+                       if (!drain) {
+                               lkp->lk_waitcount--;
+                               if (lkp->lk_waitcount == 0)
+                                       lkp->lk_flags &= ~LK_WAIT_NONZERO;
+                       }
+                       if (error)
+                               break;
+                       if (extflags & LK_SLEEPFAIL) {
+                               error = ENOLCK;
+                               break;
+                       }
+               }
        }
 
+       return error;
+}
+
 #define        SETHOLDER(lkp, pid, lid, cpu_id)                                \
 do {                                                                   \
        if ((lkp)->lk_flags & LK_SPIN)                                  \
@@ -273,7 +294,8 @@
 
 #define        WAKEUP_WAITER(lkp)                                              \
 do {                                                                   \
-       if (((lkp)->lk_flags & LK_SPIN) == 0 && (lkp)->lk_waitcount) {  \
+       if (((lkp)->lk_flags & (LK_SPIN | LK_WAIT_NONZERO)) ==          \
+           LK_WAIT_NONZERO) {                                          \
                /* XXX Cast away volatile. */                           \
                wakeup((void *)(lkp));                                  \
        }                                                               \
@@ -561,11 +583,12 @@
                        /*
                         * Wait for exclusive locks and upgrades to clear.
                         */
-                       ACQUIRE(lkp, error, extflags, 0, lkp->lk_flags &
-                           (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE));
+                       error = acquire(lkp, extflags, 0,
+                           LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE);
                        if (error)
                                break;
                        lkp->lk_sharecount++;
+                       lkp->lk_flags |= LK_SHARE_NONZERO;
                        COUNT(lkp, l, cpu_id, 1);
                        break;
                }
@@ -574,6 +597,7 @@
                 * An alternative would be to fail with EDEADLK.
                 */
                lkp->lk_sharecount++;
+               lkp->lk_flags |= LK_SHARE_NONZERO;
                COUNT(lkp, l, cpu_id, 1);
                /* fall into downgrade */
 
@@ -582,6 +606,7 @@
                    lkp->lk_exclusivecount == 0)
                        panic("lockmgr: not holding exclusive lock");
                lkp->lk_sharecount += lkp->lk_exclusivecount;
+               lkp->lk_flags |= LK_SHARE_NONZERO;
                lkp->lk_exclusivecount = 0;
                lkp->lk_recurselevel = 0;
                lkp->lk_flags &= ~LK_HAVE_EXCL;
@@ -602,6 +627,8 @@
                 */
                if (lkp->lk_flags & LK_WANT_UPGRADE) {
                        lkp->lk_sharecount--;
+                       if (lkp->lk_sharecount == 0)
+                               lkp->lk_flags &= ~LK_SHARE_NONZERO;
                        COUNT(lkp, l, cpu_id, -1);
                        error = EBUSY;
                        break;
@@ -620,6 +647,8 @@
                if (WEHOLDIT(lkp, pid, lid, cpu_id) || lkp->lk_sharecount <= 0)
                        panic("lockmgr: upgrade exclusive lock");
                lkp->lk_sharecount--;
+               if (lkp->lk_sharecount == 0)
+                       lkp->lk_flags &= ~LK_SHARE_NONZERO;
                COUNT(lkp, l, cpu_id, -1);
                /*
                 * If we are just polling, check to see if we will block.
@@ -637,7 +666,7 @@
                         * drop to zero, then take exclusive lock.
                         */
                        lkp->lk_flags |= LK_WANT_UPGRADE;
-                       ACQUIRE(lkp, error, extflags, 0, lkp->lk_sharecount);
+                       error = acquire(lkp, extflags, 0, LK_SHARE_NONZERO);
                        lkp->lk_flags &= ~LK_WANT_UPGRADE;
                        if (error)
                                break;
@@ -688,25 +717,24 @@
                /*
                 * If we are just polling, check to see if we will sleep.
                 */
-               if ((extflags & LK_NOWAIT) && ((lkp->lk_flags &
-                    (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) ||
-                    lkp->lk_sharecount != 0)) {
+               if ((extflags & LK_NOWAIT) && (lkp->lk_flags &
+                    (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE |
+                    LK_SHARE_NONZERO))) {
                        error = EBUSY;
                        break;
                }
                /*
                 * Try to acquire the want_exclusive flag.
                 */
-               ACQUIRE(lkp, error, extflags, 0, lkp->lk_flags &
-                   (LK_HAVE_EXCL | LK_WANT_EXCL));
+               error = acquire(lkp, extflags, 0, LK_HAVE_EXCL | LK_WANT_EXCL);
                if (error)
                        break;
                lkp->lk_flags |= LK_WANT_EXCL;
                /*
                 * Wait for shared locks and upgrades to finish.
                 */
-               ACQUIRE(lkp, error, extflags, 0, lkp->lk_sharecount != 0 ||
-                      (lkp->lk_flags & LK_WANT_UPGRADE));
+               error = acquire(lkp, extflags, 0,
+                   LK_WANT_UPGRADE | LK_SHARE_NONZERO);
                lkp->lk_flags &= ~LK_WANT_EXCL;
                if (error)
                        break;
@@ -754,6 +782,8 @@
                        }
                } else if (lkp->lk_sharecount != 0) {
                        lkp->lk_sharecount--;
+                       if (lkp->lk_sharecount == 0)
+                               lkp->lk_flags &= ~LK_SHARE_NONZERO;
                        COUNT(lkp, l, cpu_id, -1);
                }
 #ifdef DIAGNOSTIC
@@ -775,17 +805,15 @@
                /*
                 * If we are just polling, check to see if we will sleep.
                 */
-               if ((extflags & LK_NOWAIT) && ((lkp->lk_flags &
-                    (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) ||
-                    lkp->lk_sharecount != 0 || lkp->lk_waitcount != 0)) {
+               if ((extflags & LK_NOWAIT) && (lkp->lk_flags &
+                    (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE |
+                    LK_SHARE_NONZERO | LK_WAIT_NONZERO))) {
                        error = EBUSY;
                        break;
                }
-               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));
+               error = acquire(lkp, extflags, 1,
+                   LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE |
+                   LK_SHARE_NONZERO | LK_WAIT_NONZERO);
                if (error)
                        break;
                lkp->lk_flags |= LK_DRAINING | LK_HAVE_EXCL;
@@ -810,8 +838,8 @@
        }
        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)) {
+             (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE |
+             LK_SHARE_NONZERO | LK_WAIT_NONZERO)) == 0)) {
                lkp->lk_flags &= ~LK_WAITDRAIN;
                wakeup((void *)&lkp->lk_flags);
        }
@@ -909,14 +937,12 @@
        /*
         * Try to acquire the want_exclusive flag.
         */
-       ACQUIRE(lkp, error, LK_SPIN, 0, lkp->lk_flags &



Home | Main Index | Thread Index | Old Index