[BACK]Return to kern_lock.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Annotation of src/sys/kern/kern_lock.c, Revision 1.33

1.33    ! thorpej     1: /*     $NetBSD: kern_lock.c,v 1.32 2000/06/10 18:44:43 sommerfeld Exp $        */
1.19      thorpej     2:
                      3: /*-
1.28      thorpej     4:  * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
1.19      thorpej     5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                      9:  * NASA Ames Research Center.
                     10:  *
                     11:  * This code is derived from software contributed to The NetBSD Foundation
                     12:  * by Ross Harvey.
                     13:  *
                     14:  * Redistribution and use in source and binary forms, with or without
                     15:  * modification, are permitted provided that the following conditions
                     16:  * are met:
                     17:  * 1. Redistributions of source code must retain the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer.
                     19:  * 2. Redistributions in binary form must reproduce the above copyright
                     20:  *    notice, this list of conditions and the following disclaimer in the
                     21:  *    documentation and/or other materials provided with the distribution.
                     22:  * 3. All advertising materials mentioning features or use of this software
                     23:  *    must display the following acknowledgement:
                     24:  *     This product includes software developed by the NetBSD
                     25:  *     Foundation, Inc. and its contributors.
                     26:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     27:  *    contributors may be used to endorse or promote products derived
                     28:  *    from this software without specific prior written permission.
                     29:  *
                     30:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     31:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     32:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     33:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     34:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     35:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     36:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     37:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     38:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     39:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     40:  * POSSIBILITY OF SUCH DAMAGE.
                     41:  */
1.2       fvdl       42:
1.1       fvdl       43: /*
                     44:  * Copyright (c) 1995
                     45:  *     The Regents of the University of California.  All rights reserved.
                     46:  *
                     47:  * This code contains ideas from software contributed to Berkeley by
                     48:  * Avadis Tevanian, Jr., Michael Wayne Young, and the Mach Operating
                     49:  * System project at Carnegie-Mellon University.
                     50:  *
                     51:  * Redistribution and use in source and binary forms, with or without
                     52:  * modification, are permitted provided that the following conditions
                     53:  * are met:
                     54:  * 1. Redistributions of source code must retain the above copyright
                     55:  *    notice, this list of conditions and the following disclaimer.
                     56:  * 2. Redistributions in binary form must reproduce the above copyright
                     57:  *    notice, this list of conditions and the following disclaimer in the
                     58:  *    documentation and/or other materials provided with the distribution.
                     59:  * 3. All advertising materials mentioning features or use of this software
                     60:  *    must display the following acknowledgement:
                     61:  *     This product includes software developed by the University of
                     62:  *     California, Berkeley and its contributors.
                     63:  * 4. Neither the name of the University nor the names of its contributors
                     64:  *    may be used to endorse or promote products derived from this software
                     65:  *    without specific prior written permission.
                     66:  *
                     67:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     68:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     69:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     70:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     71:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     72:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     73:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     74:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     75:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     76:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     77:  * SUCH DAMAGE.
                     78:  *
                     79:  *     @(#)kern_lock.c 8.18 (Berkeley) 5/21/95
                     80:  */
1.7       thorpej    81:
1.21      thorpej    82: #include "opt_multiprocessor.h"
1.7       thorpej    83: #include "opt_lockdebug.h"
1.18      chs        84: #include "opt_ddb.h"
1.1       fvdl       85:
                     86: #include <sys/param.h>
                     87: #include <sys/proc.h>
                     88: #include <sys/lock.h>
1.2       fvdl       89: #include <sys/systm.h>
1.1       fvdl       90: #include <machine/cpu.h>
                     91:
1.28      thorpej    92: #if defined(__HAVE_ATOMIC_OPERATIONS)
                     93: #include <machine/atomic.h>
                     94: #endif
                     95:
1.25      thorpej    96: #if defined(LOCKDEBUG)
                     97: #include <sys/syslog.h>
                     98: /*
                     99:  * note that stdarg.h and the ansi style va_start macro is used for both
                    100:  * ansi and traditional c compiles.
                    101:  * XXX: this requires that stdarg.h define: va_alist and va_dcl
                    102:  */
                    103: #include <machine/stdarg.h>
                    104:
1.33    ! thorpej   105: void   lock_printf(const char *fmt, ...);
1.25      thorpej   106:
                    107: int    lock_debug_syslog = 0;  /* defaults to printf, but can be patched */
                    108: #endif
                    109:
1.1       fvdl      110: /*
                    111:  * Locking primitives implementation.
                    112:  * Locks provide shared/exclusive sychronization.
                    113:  */
                    114:
1.21      thorpej   115: #if defined(LOCKDEBUG) || defined(DIAGNOSTIC) /* { */
                    116: #if defined(MULTIPROCESSOR) /* { */
1.28      thorpej   117: #if defined(__HAVE_ATOMIC_OPERATIONS) /* { */
1.21      thorpej   118: #define        COUNT_CPU(cpu_id, x)                                            \
1.30      thorpej   119:        atomic_add_ulong(&curcpu()->ci_spin_locks, (x))
1.28      thorpej   120: #else
                    121: #define        COUNT_CPU(cpu_id, x)    /* not safe */
                    122: #endif /* __HAVE_ATOMIC_OPERATIONS */ /* } */
1.21      thorpej   123: #else
                    124: u_long spin_locks;
                    125: #define        COUNT_CPU(cpu_id, x)    spin_locks += (x)
                    126: #endif /* MULTIPROCESSOR */ /* } */
                    127:
                    128: #define        COUNT(lkp, p, cpu_id, x)                                        \
                    129: do {                                                                   \
                    130:        if ((lkp)->lk_flags & LK_SPIN)                                  \
                    131:                COUNT_CPU((cpu_id), (x));                               \
                    132:        else                                                            \
                    133:                (p)->p_locks += (x);                                    \
1.30      thorpej   134: } while (/*CONSTCOND*/0)
1.1       fvdl      135: #else
1.22      mellon    136: #define COUNT(lkp, p, cpu_id, x)
1.21      thorpej   137: #endif /* LOCKDEBUG || DIAGNOSTIC */ /* } */
1.1       fvdl      138:
                    139: /*
                    140:  * Acquire a resource.
                    141:  */
1.23      thorpej   142: #define ACQUIRE(lkp, error, extflags, drain, wanted)                   \
1.19      thorpej   143:        if ((extflags) & LK_SPIN) {                                     \
                    144:                int interlocked;                                        \
                    145:                                                                        \
1.23      thorpej   146:                if ((drain) == 0)                                       \
                    147:                        (lkp)->lk_waitcount++;                          \
1.19      thorpej   148:                for (interlocked = 1;;) {                               \
                    149:                        if (wanted) {                                   \
                    150:                                if (interlocked) {                      \
                    151:                                        simple_unlock(&(lkp)->lk_interlock); \
                    152:                                        interlocked = 0;                \
                    153:                                }                                       \
                    154:                        } else if (interlocked) {                       \
                    155:                                break;                                  \
                    156:                        } else {                                        \
                    157:                                simple_lock(&(lkp)->lk_interlock);      \
                    158:                                interlocked = 1;                        \
                    159:                        }                                               \
                    160:                }                                                       \
1.23      thorpej   161:                if ((drain) == 0)                                       \
                    162:                        (lkp)->lk_waitcount--;                          \
1.19      thorpej   163:                KASSERT((wanted) == 0);                                 \
                    164:                error = 0;      /* sanity */                            \
                    165:        } else {                                                        \
                    166:                for (error = 0; wanted; ) {                             \
1.23      thorpej   167:                        if ((drain))                                    \
                    168:                                (lkp)->lk_flags |= LK_WAITDRAIN;        \
                    169:                        else                                            \
                    170:                                (lkp)->lk_waitcount++;                  \
                    171:                        /* XXX Cast away volatile. */                   \
1.31      thorpej   172:                        error = ltsleep((drain) ? &(lkp)->lk_flags :    \
1.23      thorpej   173:                            (void *)(lkp), (lkp)->lk_prio,              \
1.31      thorpej   174:                            (lkp)->lk_wmesg, (lkp)->lk_timo,            \
                    175:                            &(lkp)->lk_interlock);                      \
1.23      thorpej   176:                        if ((drain) == 0)                               \
                    177:                                (lkp)->lk_waitcount--;                  \
1.19      thorpej   178:                        if (error)                                      \
                    179:                                break;                                  \
                    180:                        if ((extflags) & LK_SLEEPFAIL) {                \
                    181:                                error = ENOLCK;                         \
                    182:                                break;                                  \
                    183:                        }                                               \
1.1       fvdl      184:                }                                                       \
                    185:        }
                    186:
1.19      thorpej   187: #define        SETHOLDER(lkp, pid, cpu_id)                                     \
                    188: do {                                                                   \
                    189:        if ((lkp)->lk_flags & LK_SPIN)                                  \
                    190:                (lkp)->lk_cpu = cpu_id;                                 \
                    191:        else                                                            \
                    192:                (lkp)->lk_lockholder = pid;                             \
1.30      thorpej   193: } while (/*CONSTCOND*/0)
1.19      thorpej   194:
                    195: #define        WEHOLDIT(lkp, pid, cpu_id)                                      \
                    196:        (((lkp)->lk_flags & LK_SPIN) != 0 ?                             \
                    197:         ((lkp)->lk_cpu == (cpu_id)) : ((lkp)->lk_lockholder == (pid)))
                    198:
1.23      thorpej   199: #define        WAKEUP_WAITER(lkp)                                              \
                    200: do {                                                                   \
                    201:        if (((lkp)->lk_flags & LK_SPIN) == 0 && (lkp)->lk_waitcount) {  \
                    202:                /* XXX Cast away volatile. */                           \
                    203:                wakeup_one((void *)(lkp));                              \
                    204:        }                                                               \
1.30      thorpej   205: } while (/*CONSTCOND*/0)
1.23      thorpej   206:
1.21      thorpej   207: #if defined(LOCKDEBUG) /* { */
                    208: #if defined(MULTIPROCESSOR) /* { */
                    209: struct simplelock spinlock_list_slock = SIMPLELOCK_INITIALIZER;
                    210:
1.27      thorpej   211: #define        SPINLOCK_LIST_LOCK()                                            \
1.29      sommerfe  212:        __cpu_simple_lock(&spinlock_list_slock.lock_data)
1.21      thorpej   213:
1.27      thorpej   214: #define        SPINLOCK_LIST_UNLOCK()                                          \
1.29      sommerfe  215:        __cpu_simple_unlock(&spinlock_list_slock.lock_data)
1.21      thorpej   216: #else
                    217: #define        SPINLOCK_LIST_LOCK()    /* nothing */
                    218:
                    219: #define        SPINLOCK_LIST_UNLOCK()  /* nothing */
                    220: #endif /* MULTIPROCESSOR */ /* } */
                    221:
                    222: TAILQ_HEAD(, lock) spinlock_list =
                    223:     TAILQ_HEAD_INITIALIZER(spinlock_list);
                    224:
                    225: #define        HAVEIT(lkp)                                                     \
                    226: do {                                                                   \
                    227:        if ((lkp)->lk_flags & LK_SPIN) {                                \
                    228:                int s = splhigh();                                      \
                    229:                SPINLOCK_LIST_LOCK();                                   \
                    230:                /* XXX Cast away volatile. */                           \
                    231:                TAILQ_INSERT_TAIL(&spinlock_list, (struct lock *)(lkp), \
                    232:                    lk_list);                                           \
                    233:                SPINLOCK_LIST_UNLOCK();                                 \
                    234:                splx(s);                                                \
                    235:        }                                                               \
1.30      thorpej   236: } while (/*CONSTCOND*/0)
1.21      thorpej   237:
                    238: #define        DONTHAVEIT(lkp)                                                 \
                    239: do {                                                                   \
                    240:        if ((lkp)->lk_flags & LK_SPIN) {                                \
                    241:                int s = splhigh();                                      \
                    242:                SPINLOCK_LIST_LOCK();                                   \
                    243:                /* XXX Cast away volatile. */                           \
                    244:                TAILQ_REMOVE(&spinlock_list, (struct lock *)(lkp),      \
                    245:                    lk_list);                                           \
                    246:                SPINLOCK_LIST_UNLOCK();                                 \
                    247:                splx(s);                                                \
                    248:        }                                                               \
1.30      thorpej   249: } while (/*CONSTCOND*/0)
1.21      thorpej   250: #else
                    251: #define        HAVEIT(lkp)             /* nothing */
                    252:
                    253: #define        DONTHAVEIT(lkp)         /* nothing */
                    254: #endif /* LOCKDEBUG */ /* } */
                    255:
1.25      thorpej   256: #if defined(LOCKDEBUG)
                    257: /*
                    258:  * Lock debug printing routine; can be configured to print to console
                    259:  * or log to syslog.
                    260:  */
                    261: void
                    262: lock_printf(const char *fmt, ...)
                    263: {
                    264:        va_list ap;
                    265:
                    266:        va_start(ap, fmt);
                    267:        if (lock_debug_syslog)
                    268:                vlog(LOG_DEBUG, fmt, ap);
                    269:        else
                    270:                vprintf(fmt, ap);
                    271:        va_end(ap);
                    272: }
                    273: #endif /* LOCKDEBUG */
                    274:
1.1       fvdl      275: /*
                    276:  * Initialize a lock; required before use.
                    277:  */
                    278: void
1.33    ! thorpej   279: lockinit(struct lock *lkp, int prio, const char *wmesg, int timo, int flags)
1.1       fvdl      280: {
                    281:
1.8       perry     282:        memset(lkp, 0, sizeof(struct lock));
1.1       fvdl      283:        simple_lock_init(&lkp->lk_interlock);
                    284:        lkp->lk_flags = flags & LK_EXTFLG_MASK;
1.19      thorpej   285:        if (flags & LK_SPIN)
                    286:                lkp->lk_cpu = LK_NOCPU;
                    287:        else {
                    288:                lkp->lk_lockholder = LK_NOPROC;
                    289:                lkp->lk_prio = prio;
                    290:                lkp->lk_timo = timo;
                    291:        }
                    292:        lkp->lk_wmesg = wmesg;  /* just a name for spin locks */
1.1       fvdl      293: }
                    294:
                    295: /*
                    296:  * Determine the status of a lock.
                    297:  */
                    298: int
1.33    ! thorpej   299: lockstatus(struct lock *lkp)
1.1       fvdl      300: {
                    301:        int lock_type = 0;
                    302:
                    303:        simple_lock(&lkp->lk_interlock);
                    304:        if (lkp->lk_exclusivecount != 0)
                    305:                lock_type = LK_EXCLUSIVE;
                    306:        else if (lkp->lk_sharecount != 0)
                    307:                lock_type = LK_SHARED;
                    308:        simple_unlock(&lkp->lk_interlock);
                    309:        return (lock_type);
                    310: }
                    311:
                    312: /*
1.32      sommerfe  313:  * XXX XXX kludge around another kludge..
                    314:  *
                    315:  * vfs_shutdown() may be called from interrupt context, either as a result
                    316:  * of a panic, or from the debugger.   It proceeds to call
                    317:  * sys_sync(&proc0, ...), pretending its running on behalf of proc0
                    318:  *
                    319:  * We would like to make an attempt to sync the filesystems in this case, so
                    320:  * if this happens, we treat attempts to acquire locks specially.
                    321:  * All locks are acquired on behalf of proc0.
                    322:  *
                    323:  * If we've already paniced, we don't block waiting for locks, but
                    324:  * just barge right ahead since we're already going down in flames.
                    325:  */
                    326:
                    327: /*
1.1       fvdl      328:  * Set, change, or release a lock.
                    329:  *
                    330:  * Shared requests increment the shared count. Exclusive requests set the
                    331:  * LK_WANT_EXCL flag (preventing further shared locks), and wait for already
                    332:  * accepted shared locks and shared-to-exclusive upgrades to go away.
                    333:  */
                    334: int
1.33    ! thorpej   335: lockmgr(__volatile struct lock *lkp, u_int flags,
        !           336:     struct simplelock *interlkp)
1.1       fvdl      337: {
                    338:        int error;
                    339:        pid_t pid;
                    340:        int extflags;
1.24      thorpej   341:        cpuid_t cpu_id;
1.6       fvdl      342:        struct proc *p = curproc;
1.32      sommerfe  343:        int lock_shutdown_noblock = 0;
1.1       fvdl      344:
                    345:        error = 0;
1.19      thorpej   346:
1.1       fvdl      347:        simple_lock(&lkp->lk_interlock);
                    348:        if (flags & LK_INTERLOCK)
                    349:                simple_unlock(interlkp);
                    350:        extflags = (flags | lkp->lk_flags) & LK_EXTFLG_MASK;
1.19      thorpej   351:
1.21      thorpej   352: #ifdef DIAGNOSTIC /* { */
1.19      thorpej   353:        /*
                    354:         * Don't allow spins on sleep locks and don't allow sleeps
                    355:         * on spin locks.
                    356:         */
                    357:        if ((flags ^ lkp->lk_flags) & LK_SPIN)
                    358:                panic("lockmgr: sleep/spin mismatch\n");
1.21      thorpej   359: #endif /* } */
1.19      thorpej   360:
                    361:        if (extflags & LK_SPIN)
                    362:                pid = LK_KERNPROC;
                    363:        else {
1.32      sommerfe  364:                if (p == NULL) {
                    365:                        if (!doing_shutdown) {
                    366: #ifdef DIAGNOSTIC
                    367:                                panic("lockmgr: no context");
                    368: #endif
                    369:                        } else {
                    370:                                p = &proc0;
                    371:                                if (panicstr && (!(flags & LK_NOWAIT))) {
                    372:                                        flags |= LK_NOWAIT;
                    373:                                        lock_shutdown_noblock = 1;
                    374:                                }
                    375:                        }
                    376:                }
1.19      thorpej   377:                pid = p->p_pid;
                    378:        }
1.24      thorpej   379:        cpu_id = cpu_number();
1.19      thorpej   380:
1.1       fvdl      381:        /*
                    382:         * Once a lock has drained, the LK_DRAINING flag is set and an
                    383:         * exclusive lock is returned. The only valid operation thereafter
                    384:         * is a single release of that exclusive lock. This final release
                    385:         * clears the LK_DRAINING flag and sets the LK_DRAINED flag. Any
                    386:         * further requests of any sort will result in a panic. The bits
                    387:         * selected for these two flags are chosen so that they will be set
                    388:         * in memory that is freed (freed memory is filled with 0xdeadbeef).
                    389:         * The final release is permitted to give a new lease on life to
                    390:         * the lock by specifying LK_REENABLE.
                    391:         */
                    392:        if (lkp->lk_flags & (LK_DRAINING|LK_DRAINED)) {
1.28      thorpej   393: #ifdef DIAGNOSTIC /* { */
1.1       fvdl      394:                if (lkp->lk_flags & LK_DRAINED)
                    395:                        panic("lockmgr: using decommissioned lock");
                    396:                if ((flags & LK_TYPE_MASK) != LK_RELEASE ||
1.19      thorpej   397:                    WEHOLDIT(lkp, pid, cpu_id) == 0)
1.1       fvdl      398:                        panic("lockmgr: non-release on draining lock: %d\n",
                    399:                            flags & LK_TYPE_MASK);
1.28      thorpej   400: #endif /* DIAGNOSTIC */ /* } */
1.1       fvdl      401:                lkp->lk_flags &= ~LK_DRAINING;
                    402:                if ((flags & LK_REENABLE) == 0)
                    403:                        lkp->lk_flags |= LK_DRAINED;
                    404:        }
                    405:
                    406:        switch (flags & LK_TYPE_MASK) {
                    407:
                    408:        case LK_SHARED:
1.19      thorpej   409:                if (WEHOLDIT(lkp, pid, cpu_id) == 0) {
1.1       fvdl      410:                        /*
                    411:                         * If just polling, check to see if we will block.
                    412:                         */
                    413:                        if ((extflags & LK_NOWAIT) && (lkp->lk_flags &
                    414:                            (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE))) {
                    415:                                error = EBUSY;
                    416:                                break;
                    417:                        }
                    418:                        /*
                    419:                         * Wait for exclusive locks and upgrades to clear.
                    420:                         */
1.23      thorpej   421:                        ACQUIRE(lkp, error, extflags, 0, lkp->lk_flags &
1.1       fvdl      422:                            (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE));
                    423:                        if (error)
                    424:                                break;
                    425:                        lkp->lk_sharecount++;
1.21      thorpej   426:                        COUNT(lkp, p, cpu_id, 1);
1.1       fvdl      427:                        break;
                    428:                }
                    429:                /*
                    430:                 * We hold an exclusive lock, so downgrade it to shared.
                    431:                 * An alternative would be to fail with EDEADLK.
                    432:                 */
                    433:                lkp->lk_sharecount++;
1.21      thorpej   434:                COUNT(lkp, p, cpu_id, 1);
1.1       fvdl      435:                /* fall into downgrade */
                    436:
                    437:        case LK_DOWNGRADE:
1.19      thorpej   438:                if (WEHOLDIT(lkp, pid, cpu_id) == 0 ||
                    439:                    lkp->lk_exclusivecount == 0)
1.1       fvdl      440:                        panic("lockmgr: not holding exclusive lock");
                    441:                lkp->lk_sharecount += lkp->lk_exclusivecount;
                    442:                lkp->lk_exclusivecount = 0;
1.15      fvdl      443:                lkp->lk_recurselevel = 0;
1.1       fvdl      444:                lkp->lk_flags &= ~LK_HAVE_EXCL;
1.19      thorpej   445:                SETHOLDER(lkp, LK_NOPROC, LK_NOCPU);
1.21      thorpej   446:                DONTHAVEIT(lkp);
1.23      thorpej   447:                WAKEUP_WAITER(lkp);
1.1       fvdl      448:                break;
                    449:
                    450:        case LK_EXCLUPGRADE:
                    451:                /*
                    452:                 * If another process is ahead of us to get an upgrade,
                    453:                 * then we want to fail rather than have an intervening
                    454:                 * exclusive access.
                    455:                 */
                    456:                if (lkp->lk_flags & LK_WANT_UPGRADE) {
                    457:                        lkp->lk_sharecount--;
1.21      thorpej   458:                        COUNT(lkp, p, cpu_id, -1);
1.1       fvdl      459:                        error = EBUSY;
                    460:                        break;
                    461:                }
                    462:                /* fall into normal upgrade */
                    463:
                    464:        case LK_UPGRADE:
                    465:                /*
                    466:                 * Upgrade a shared lock to an exclusive one. If another
                    467:                 * shared lock has already requested an upgrade to an
                    468:                 * exclusive lock, our shared lock is released and an
                    469:                 * exclusive lock is requested (which will be granted
                    470:                 * after the upgrade). If we return an error, the file
                    471:                 * will always be unlocked.
                    472:                 */
1.19      thorpej   473:                if (WEHOLDIT(lkp, pid, cpu_id) || lkp->lk_sharecount <= 0)
1.1       fvdl      474:                        panic("lockmgr: upgrade exclusive lock");
                    475:                lkp->lk_sharecount--;
1.21      thorpej   476:                COUNT(lkp, p, cpu_id, -1);
1.1       fvdl      477:                /*
                    478:                 * If we are just polling, check to see if we will block.
                    479:                 */
                    480:                if ((extflags & LK_NOWAIT) &&
                    481:                    ((lkp->lk_flags & LK_WANT_UPGRADE) ||
                    482:                     lkp->lk_sharecount > 1)) {
                    483:                        error = EBUSY;
                    484:                        break;
                    485:                }
                    486:                if ((lkp->lk_flags & LK_WANT_UPGRADE) == 0) {
                    487:                        /*
                    488:                         * We are first shared lock to request an upgrade, so
                    489:                         * request upgrade and wait for the shared count to
                    490:                         * drop to zero, then take exclusive lock.
                    491:                         */
                    492:                        lkp->lk_flags |= LK_WANT_UPGRADE;
1.23      thorpej   493:                        ACQUIRE(lkp, error, extflags, 0, lkp->lk_sharecount);
1.1       fvdl      494:                        lkp->lk_flags &= ~LK_WANT_UPGRADE;
                    495:                        if (error)
                    496:                                break;
                    497:                        lkp->lk_flags |= LK_HAVE_EXCL;
1.19      thorpej   498:                        SETHOLDER(lkp, pid, cpu_id);
1.21      thorpej   499:                        HAVEIT(lkp);
1.1       fvdl      500:                        if (lkp->lk_exclusivecount != 0)
                    501:                                panic("lockmgr: non-zero exclusive count");
                    502:                        lkp->lk_exclusivecount = 1;
1.15      fvdl      503:                        if (extflags & LK_SETRECURSE)
                    504:                                lkp->lk_recurselevel = 1;
1.21      thorpej   505:                        COUNT(lkp, p, cpu_id, 1);
1.1       fvdl      506:                        break;
                    507:                }
                    508:                /*
                    509:                 * Someone else has requested upgrade. Release our shared
                    510:                 * lock, awaken upgrade requestor if we are the last shared
                    511:                 * lock, then request an exclusive lock.
                    512:                 */
1.23      thorpej   513:                if (lkp->lk_sharecount == 0)
                    514:                        WAKEUP_WAITER(lkp);
1.1       fvdl      515:                /* fall into exclusive request */
                    516:
                    517:        case LK_EXCLUSIVE:
1.19      thorpej   518:                if (WEHOLDIT(lkp, pid, cpu_id)) {
1.1       fvdl      519:                        /*
1.19      thorpej   520:                         * Recursive lock.
1.1       fvdl      521:                         */
1.15      fvdl      522:                        if ((extflags & LK_CANRECURSE) == 0 &&
1.16      sommerfe  523:                             lkp->lk_recurselevel == 0) {
                    524:                                if (extflags & LK_RECURSEFAIL) {
                    525:                                        error = EDEADLK;
                    526:                                        break;
                    527:                                } else
                    528:                                        panic("lockmgr: locking against myself");
                    529:                        }
1.1       fvdl      530:                        lkp->lk_exclusivecount++;
1.15      fvdl      531:                        if (extflags & LK_SETRECURSE &&
                    532:                            lkp->lk_recurselevel == 0)
                    533:                                lkp->lk_recurselevel = lkp->lk_exclusivecount;
1.21      thorpej   534:                        COUNT(lkp, p, cpu_id, 1);
1.1       fvdl      535:                        break;
                    536:                }
                    537:                /*
                    538:                 * If we are just polling, check to see if we will sleep.
                    539:                 */
                    540:                if ((extflags & LK_NOWAIT) && ((lkp->lk_flags &
                    541:                     (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) ||
                    542:                     lkp->lk_sharecount != 0)) {
                    543:                        error = EBUSY;
                    544:                        break;
                    545:                }
                    546:                /*
                    547:                 * Try to acquire the want_exclusive flag.
                    548:                 */
1.23      thorpej   549:                ACQUIRE(lkp, error, extflags, 0, lkp->lk_flags &
1.1       fvdl      550:                    (LK_HAVE_EXCL | LK_WANT_EXCL));
                    551:                if (error)
                    552:                        break;
                    553:                lkp->lk_flags |= LK_WANT_EXCL;
                    554:                /*
                    555:                 * Wait for shared locks and upgrades to finish.
                    556:                 */
1.23      thorpej   557:                ACQUIRE(lkp, error, extflags, 0, lkp->lk_sharecount != 0 ||
1.1       fvdl      558:                       (lkp->lk_flags & LK_WANT_UPGRADE));
                    559:                lkp->lk_flags &= ~LK_WANT_EXCL;
                    560:                if (error)
                    561:                        break;
                    562:                lkp->lk_flags |= LK_HAVE_EXCL;
1.19      thorpej   563:                SETHOLDER(lkp, pid, cpu_id);
1.21      thorpej   564:                HAVEIT(lkp);
1.1       fvdl      565:                if (lkp->lk_exclusivecount != 0)
                    566:                        panic("lockmgr: non-zero exclusive count");
                    567:                lkp->lk_exclusivecount = 1;
1.15      fvdl      568:                if (extflags & LK_SETRECURSE)
                    569:                        lkp->lk_recurselevel = 1;
1.21      thorpej   570:                COUNT(lkp, p, cpu_id, 1);
1.1       fvdl      571:                break;
                    572:
                    573:        case LK_RELEASE:
                    574:                if (lkp->lk_exclusivecount != 0) {
1.19      thorpej   575:                        if (WEHOLDIT(lkp, pid, cpu_id) == 0) {
                    576:                                if (lkp->lk_flags & LK_SPIN) {
                    577:                                        panic("lockmgr: processor %lu, not "
                    578:                                            "exclusive lock holder %lu "
                    579:                                            "unlocking", cpu_id, lkp->lk_cpu);
                    580:                                } else {
                    581:                                        panic("lockmgr: pid %d, not "
                    582:                                            "exclusive lock holder %d "
                    583:                                            "unlocking", pid,
                    584:                                            lkp->lk_lockholder);
                    585:                                }
                    586:                        }
1.15      fvdl      587:                        if (lkp->lk_exclusivecount == lkp->lk_recurselevel)
                    588:                                lkp->lk_recurselevel = 0;
1.1       fvdl      589:                        lkp->lk_exclusivecount--;
1.21      thorpej   590:                        COUNT(lkp, p, cpu_id, -1);
1.1       fvdl      591:                        if (lkp->lk_exclusivecount == 0) {
                    592:                                lkp->lk_flags &= ~LK_HAVE_EXCL;
1.19      thorpej   593:                                SETHOLDER(lkp, LK_NOPROC, LK_NOCPU);
1.21      thorpej   594:                                DONTHAVEIT(lkp);
1.1       fvdl      595:                        }
                    596:                } else if (lkp->lk_sharecount != 0) {
                    597:                        lkp->lk_sharecount--;
1.21      thorpej   598:                        COUNT(lkp, p, cpu_id, -1);
1.1       fvdl      599:                }
1.23      thorpej   600:                WAKEUP_WAITER(lkp);
1.1       fvdl      601:                break;
                    602:
                    603:        case LK_DRAIN:
                    604:                /*
                    605:                 * Check that we do not already hold the lock, as it can
                    606:                 * never drain if we do. Unfortunately, we have no way to
                    607:                 * check for holding a shared lock, but at least we can
                    608:                 * check for an exclusive one.
                    609:                 */
1.19      thorpej   610:                if (WEHOLDIT(lkp, pid, cpu_id))
1.1       fvdl      611:                        panic("lockmgr: draining against myself");
                    612:                /*
                    613:                 * If we are just polling, check to see if we will sleep.
                    614:                 */
                    615:                if ((extflags & LK_NOWAIT) && ((lkp->lk_flags &
                    616:                     (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) ||
                    617:                     lkp->lk_sharecount != 0 || lkp->lk_waitcount != 0)) {
                    618:                        error = EBUSY;
                    619:                        break;
                    620:                }
1.23      thorpej   621:                ACQUIRE(lkp, error, extflags, 1,
                    622:                    ((lkp->lk_flags &
                    623:                     (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) ||
                    624:                     lkp->lk_sharecount != 0 ||
                    625:                     lkp->lk_waitcount != 0));
                    626:                if (error)
                    627:                        break;
1.1       fvdl      628:                lkp->lk_flags |= LK_DRAINING | LK_HAVE_EXCL;
1.19      thorpej   629:                SETHOLDER(lkp, pid, cpu_id);
1.21      thorpej   630:                HAVEIT(lkp);
1.1       fvdl      631:                lkp->lk_exclusivecount = 1;
1.15      fvdl      632:                /* XXX unlikely that we'd want this */
                    633:                if (extflags & LK_SETRECURSE)
                    634:                        lkp->lk_recurselevel = 1;
1.21      thorpej   635:                COUNT(lkp, p, cpu_id, 1);
1.1       fvdl      636:                break;
                    637:
                    638:        default:
                    639:                simple_unlock(&lkp->lk_interlock);
                    640:                panic("lockmgr: unknown locktype request %d",
                    641:                    flags & LK_TYPE_MASK);
                    642:                /* NOTREACHED */
                    643:        }
1.23      thorpej   644:        if ((lkp->lk_flags & (LK_WAITDRAIN|LK_SPIN)) == LK_WAITDRAIN &&
                    645:            ((lkp->lk_flags &
                    646:              (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) == 0 &&
1.1       fvdl      647:             lkp->lk_sharecount == 0 && lkp->lk_waitcount == 0)) {
                    648:                lkp->lk_flags &= ~LK_WAITDRAIN;
1.20      thorpej   649:                wakeup_one((void *)&lkp->lk_flags);
1.1       fvdl      650:        }
1.32      sommerfe  651:        /*
                    652:         * Note that this panic will be a recursive panic, since
                    653:         * we only set lock_shutdown_noblock above if panicstr != NULL.
                    654:         */
                    655:        if (error && lock_shutdown_noblock)
                    656:                panic("lockmgr: deadlock (see previous panic)");
                    657:
1.1       fvdl      658:        simple_unlock(&lkp->lk_interlock);
                    659:        return (error);
                    660: }
                    661:
                    662: /*
                    663:  * Print out information about state of a lock. Used by VOP_PRINT
                    664:  * routines to display ststus about contained locks.
                    665:  */
1.2       fvdl      666: void
1.33    ! thorpej   667: lockmgr_printinfo(__volatile struct lock *lkp)
1.1       fvdl      668: {
                    669:
                    670:        if (lkp->lk_sharecount)
                    671:                printf(" lock type %s: SHARED (count %d)", lkp->lk_wmesg,
                    672:                    lkp->lk_sharecount);
1.19      thorpej   673:        else if (lkp->lk_flags & LK_HAVE_EXCL) {
                    674:                printf(" lock type %s: EXCL (count %d) by ",
                    675:                    lkp->lk_wmesg, lkp->lk_exclusivecount);
                    676:                if (lkp->lk_flags & LK_SPIN)
                    677:                        printf("processor %lu", lkp->lk_cpu);
                    678:                else
                    679:                        printf("pid %d", lkp->lk_lockholder);
                    680:        } else
                    681:                printf(" not locked");
                    682:        if ((lkp->lk_flags & LK_SPIN) == 0 && lkp->lk_waitcount > 0)
1.1       fvdl      683:                printf(" with %d pending", lkp->lk_waitcount);
                    684: }
                    685:
1.21      thorpej   686: #if defined(LOCKDEBUG) /* { */
                    687: TAILQ_HEAD(, simplelock) simplelock_list =
                    688:     TAILQ_HEAD_INITIALIZER(simplelock_list);
                    689:
                    690: #if defined(MULTIPROCESSOR) /* { */
                    691: struct simplelock simplelock_list_slock = SIMPLELOCK_INITIALIZER;
                    692:
                    693: #define        SLOCK_LIST_LOCK()                                               \
1.29      sommerfe  694:        __cpu_simple_lock(&simplelock_list_slock.lock_data)
1.21      thorpej   695:
                    696: #define        SLOCK_LIST_UNLOCK()                                             \
1.29      sommerfe  697:        __cpu_simple_unlock(&simplelock_list_slock.lock_data)
1.21      thorpej   698:
1.28      thorpej   699: #if defined(__HAVE_ATOMIC_OPERATIONS) /* { */
1.21      thorpej   700: #define        SLOCK_COUNT(x)                                                  \
1.28      thorpej   701:        atomic_add_ulong(&curcpu()->ci_simple_locks, (x))
                    702: #else
                    703: #define        SLOCK_COUNT(x)          /* not safe */
                    704: #endif /* __HAVE_ATOMIC_OPERATIONS */ /* } */
1.21      thorpej   705: #else
                    706: u_long simple_locks;
                    707:
                    708: #define        SLOCK_LIST_LOCK()       /* nothing */
                    709:
                    710: #define        SLOCK_LIST_UNLOCK()     /* nothing */
                    711:
                    712: #define        SLOCK_COUNT(x)          simple_locks += (x)
                    713: #endif /* MULTIPROCESSOR */ /* } */
                    714:
                    715: #ifdef DDB /* { */
1.18      chs       716: int simple_lock_debugger = 0;
1.21      thorpej   717: #define        SLOCK_DEBUGGER()        if (simple_lock_debugger) Debugger()
                    718: #else
                    719: #define        SLOCK_DEBUGGER()        /* nothing */
                    720: #endif /* } */
                    721:
1.26      sommerfe  722: #ifdef MULTIPROCESSOR
                    723: #define SLOCK_MP()             lock_printf("on cpu %d\n", cpu_number())
                    724: #else
                    725: #define SLOCK_MP()             /* nothing */
                    726: #endif
                    727:
1.21      thorpej   728: #define        SLOCK_WHERE(str, alp, id, l)                                    \
                    729: do {                                                                   \
1.25      thorpej   730:        lock_printf(str);                                               \
1.33    ! thorpej   731:        lock_printf("lock: %p, currently at: %s:%d\n", (alp), (id), (l)); \
1.26      sommerfe  732:        SLOCK_MP();                                                     \
1.21      thorpej   733:        if ((alp)->lock_file != NULL)                                   \
1.25      thorpej   734:                lock_printf("last locked: %s:%d\n", (alp)->lock_file,   \
1.21      thorpej   735:                    (alp)->lock_line);                                  \
                    736:        if ((alp)->unlock_file != NULL)                                 \
1.25      thorpej   737:                lock_printf("last unlocked: %s:%d\n", (alp)->unlock_file, \
1.21      thorpej   738:                    (alp)->unlock_line);                                \
                    739:        SLOCK_DEBUGGER();                                               \
1.30      thorpej   740: } while (/*CONSTCOND*/0)
1.12      chs       741:
1.1       fvdl      742: /*
                    743:  * Simple lock functions so that the debugger can see from whence
                    744:  * they are being called.
                    745:  */
                    746: void
1.33    ! thorpej   747: simple_lock_init(struct simplelock *alp)
1.1       fvdl      748: {
1.21      thorpej   749:
                    750: #if defined(MULTIPROCESSOR) /* { */
1.27      thorpej   751:        __cpu_simple_lock_init(&alp->lock_data);
1.21      thorpej   752: #else
1.27      thorpej   753:        alp->lock_data = __SIMPLELOCK_UNLOCKED;
1.21      thorpej   754: #endif /* } */
1.5       chs       755:        alp->lock_file = NULL;
                    756:        alp->lock_line = 0;
                    757:        alp->unlock_file = NULL;
                    758:        alp->unlock_line = 0;
1.10      thorpej   759:        alp->lock_holder = 0;
1.1       fvdl      760: }
                    761:
                    762: void
1.33    ! thorpej   763: _simple_lock(__volatile struct simplelock *alp, const char *id, int l)
1.1       fvdl      764: {
1.24      thorpej   765:        cpuid_t cpu_id = cpu_number();
1.12      chs       766:        int s;
                    767:
1.18      chs       768:        s = splhigh();
1.21      thorpej   769:
                    770:        /*
                    771:         * MULTIPROCESSOR case: This is `safe' since if it's not us, we
                    772:         * don't take any action, and just fall into the normal spin case.
                    773:         */
1.27      thorpej   774:        if (alp->lock_data == __SIMPLELOCK_LOCKED) {
1.21      thorpej   775: #if defined(MULTIPROCESSOR) /* { */
                    776:                if (alp->lock_holder == cpu_id) {
                    777:                        SLOCK_WHERE("simple_lock: locking against myself\n",
                    778:                            alp, id, l);
                    779:                        goto out;
1.1       fvdl      780:                }
1.21      thorpej   781: #else
                    782:                SLOCK_WHERE("simple_lock: lock held\n", alp, id, l);
                    783:                goto out;
                    784: #endif /* MULTIPROCESSOR */ /* } */
1.1       fvdl      785:        }
1.21      thorpej   786:
                    787: #if defined(MULTIPROCESSOR) /* { */
                    788:        /* Acquire the lock before modifying any fields. */
1.27      thorpej   789:        __cpu_simple_lock(&alp->lock_data);
1.21      thorpej   790: #else
1.27      thorpej   791:        alp->lock_data = __SIMPLELOCK_LOCKED;
1.21      thorpej   792: #endif /* } */
                    793:
1.5       chs       794:        alp->lock_file = id;
                    795:        alp->lock_line = l;
1.21      thorpej   796:        alp->lock_holder = cpu_id;
                    797:
                    798:        SLOCK_LIST_LOCK();
                    799:        /* XXX Cast away volatile */
                    800:        TAILQ_INSERT_TAIL(&simplelock_list, (struct simplelock *)alp, list);
                    801:        SLOCK_LIST_UNLOCK();
                    802:
                    803:        SLOCK_COUNT(1);
                    804:
                    805:  out:
1.18      chs       806:        splx(s);
1.1       fvdl      807: }
                    808:
                    809: int
1.33    ! thorpej   810: _simple_lock_try(__volatile struct simplelock *alp, const char *id, int l)
1.1       fvdl      811: {
1.24      thorpej   812:        cpuid_t cpu_id = cpu_number();
1.21      thorpej   813:        int s, rv = 0;
1.1       fvdl      814:
1.18      chs       815:        s = splhigh();
1.21      thorpej   816:
                    817:        /*
                    818:         * MULTIPROCESSOR case: This is `safe' since if it's not us, we
                    819:         * don't take any action.
                    820:         */
                    821: #if defined(MULTIPROCESSOR) /* { */
1.27      thorpej   822:        if ((rv = __cpu_simple_lock_try(&alp->lock_data)) == 0) {
1.21      thorpej   823:                if (alp->lock_holder == cpu_id)
                    824:                        SLOCK_WHERE("simple_lock_try: locking against myself\n",
1.26      sommerfe  825:                            alp, id, l);
1.21      thorpej   826:                goto out;
                    827:        }
                    828: #else
1.27      thorpej   829:        if (alp->lock_data == __SIMPLELOCK_LOCKED) {
1.21      thorpej   830:                SLOCK_WHERE("simple_lock_try: lock held\n", alp, id, l);
                    831:                goto out;
1.18      chs       832:        }
1.27      thorpej   833:        alp->lock_data = __SIMPLELOCK_LOCKED;
1.21      thorpej   834: #endif /* MULTIPROCESSOR */ /* } */
                    835:
                    836:        /*
                    837:         * At this point, we have acquired the lock.
                    838:         */
                    839:
                    840:        rv = 1;
1.18      chs       841:
1.5       chs       842:        alp->lock_file = id;
                    843:        alp->lock_line = l;
1.21      thorpej   844:        alp->lock_holder = cpu_id;
                    845:
                    846:        SLOCK_LIST_LOCK();
                    847:        /* XXX Cast away volatile. */
                    848:        TAILQ_INSERT_TAIL(&simplelock_list, (struct simplelock *)alp, list);
                    849:        SLOCK_LIST_UNLOCK();
                    850:
                    851:        SLOCK_COUNT(1);
                    852:
                    853:  out:
1.12      chs       854:        splx(s);
1.21      thorpej   855:        return (rv);
1.1       fvdl      856: }
                    857:
                    858: void
1.33    ! thorpej   859: _simple_unlock(__volatile struct simplelock *alp, const char *id, int l)
1.1       fvdl      860: {
1.12      chs       861:        int s;
1.1       fvdl      862:
1.18      chs       863:        s = splhigh();
1.21      thorpej   864:
                    865:        /*
                    866:         * MULTIPROCESSOR case: This is `safe' because we think we hold
                    867:         * the lock, and if we don't, we don't take any action.
                    868:         */
1.27      thorpej   869:        if (alp->lock_data == __SIMPLELOCK_UNLOCKED) {
1.21      thorpej   870:                SLOCK_WHERE("simple_unlock: lock not held\n",
                    871:                    alp, id, l);
                    872:                goto out;
                    873:        }
                    874:
                    875:        SLOCK_LIST_LOCK();
                    876:        TAILQ_REMOVE(&simplelock_list, alp, list);
                    877:        SLOCK_LIST_UNLOCK();
                    878:
                    879:        SLOCK_COUNT(-1);
                    880:
                    881:        alp->list.tqe_next = NULL;      /* sanity */
                    882:        alp->list.tqe_prev = NULL;      /* sanity */
                    883:
1.5       chs       884:        alp->unlock_file = id;
                    885:        alp->unlock_line = l;
1.21      thorpej   886:
                    887: #if defined(MULTIPROCESSOR) /* { */
1.26      sommerfe  888:        alp->lock_holder = LK_NOCPU;
1.21      thorpej   889:        /* Now that we've modified all fields, release the lock. */
1.27      thorpej   890:        __cpu_simple_unlock(&alp->lock_data);
1.21      thorpej   891: #else
1.27      thorpej   892:        alp->lock_data = __SIMPLELOCK_UNLOCKED;
1.21      thorpej   893: #endif /* } */
                    894:
                    895:  out:
1.18      chs       896:        splx(s);
1.12      chs       897: }
                    898:
                    899: void
1.33    ! thorpej   900: simple_lock_dump(void)
1.12      chs       901: {
                    902:        struct simplelock *alp;
                    903:        int s;
                    904:
                    905:        s = splhigh();
1.21      thorpej   906:        SLOCK_LIST_LOCK();
1.25      thorpej   907:        lock_printf("all simple locks:\n");
1.21      thorpej   908:        for (alp = TAILQ_FIRST(&simplelock_list); alp != NULL;
                    909:             alp = TAILQ_NEXT(alp, list)) {
1.25      thorpej   910:                lock_printf("%p CPU %lu %s:%d\n", alp, alp->lock_holder,
1.21      thorpej   911:                    alp->lock_file, alp->lock_line);
1.12      chs       912:        }
1.21      thorpej   913:        SLOCK_LIST_UNLOCK();
1.12      chs       914:        splx(s);
                    915: }
                    916:
                    917: void
1.33    ! thorpej   918: simple_lock_freecheck(void *start, void *end)
1.12      chs       919: {
                    920:        struct simplelock *alp;
                    921:        int s;
                    922:
                    923:        s = splhigh();
1.21      thorpej   924:        SLOCK_LIST_LOCK();
                    925:        for (alp = TAILQ_FIRST(&simplelock_list); alp != NULL;
                    926:             alp = TAILQ_NEXT(alp, list)) {
1.12      chs       927:                if ((void *)alp >= start && (void *)alp < end) {
1.25      thorpej   928:                        lock_printf("freeing simple_lock %p CPU %lu %s:%d\n",
1.21      thorpej   929:                            alp, alp->lock_holder, alp->lock_file,
                    930:                            alp->lock_line);
                    931:                        SLOCK_DEBUGGER();
1.12      chs       932:                }
                    933:        }
1.21      thorpej   934:        SLOCK_LIST_UNLOCK();
1.12      chs       935:        splx(s);
1.1       fvdl      936: }
1.21      thorpej   937: #endif /* LOCKDEBUG */ /* } */

CVSweb <webmaster@jp.NetBSD.org>