168762Smckusick /* 268762Smckusick * Copyright (c) 1995 368762Smckusick * The Regents of the University of California. All rights reserved. 468762Smckusick * 568775Smckusick * This code contains ideas from software contributed to Berkeley by 668762Smckusick * Avadis Tevanian, Jr., Michael Wayne Young, and the Mach Operating 768762Smckusick * System project at Carnegie-Mellon University. 868762Smckusick * 968762Smckusick * %sccs.include.redist.c% 1068762Smckusick * 11*69577Smckusick * @(#)kern_lock.c 8.16 (Berkeley) 05/20/95 1268762Smckusick */ 1368762Smckusick 1468762Smckusick #include <sys/param.h> 1568762Smckusick #include <sys/proc.h> 1668762Smckusick #include <sys/lock.h> 1769536Smckusick #include <machine/cpu.h> 1868762Smckusick 1968762Smckusick /* 2068762Smckusick * Locking primitives implementation. 2168762Smckusick * Locks provide shared/exclusive sychronization. 2268762Smckusick */ 2368762Smckusick 2469527Smckusick #ifdef DEBUG 2569527Smckusick #define COUNT(p, x) if (p) (p)->p_locks += (x) 2669527Smckusick #else 2769527Smckusick #define COUNT(p, x) 2869527Smckusick #endif 2969527Smckusick 3068762Smckusick #if NCPUS > 1 3168762Smckusick 3268762Smckusick /* 3368762Smckusick * For multiprocessor system, try spin lock first. 3468762Smckusick * 3568762Smckusick * This should be inline expanded below, but we cannot have #if 3668762Smckusick * inside a multiline define. 3768762Smckusick */ 3868762Smckusick int lock_wait_time = 100; 3968762Smckusick #define PAUSE(lkp, wanted) \ 4068762Smckusick if (lock_wait_time > 0) { \ 4168762Smckusick int i; \ 4268762Smckusick \ 4368933Smckusick simple_unlock(&lkp->lk_interlock); \ 4468762Smckusick for (i = lock_wait_time; i > 0; i--) \ 4568762Smckusick if (!(wanted)) \ 4668762Smckusick break; \ 4768933Smckusick simple_lock(&lkp->lk_interlock); \ 4868762Smckusick } \ 4968762Smckusick if (!(wanted)) \ 5068762Smckusick break; 5168762Smckusick 5268762Smckusick #else /* NCPUS == 1 */ 5368762Smckusick 5468762Smckusick /* 5568762Smckusick * It is an error to spin on a uniprocessor as nothing will ever cause 5668933Smckusick * the simple lock to clear while we are executing. 5768762Smckusick */ 5868762Smckusick #define PAUSE(lkp, wanted) 5968762Smckusick 6068762Smckusick #endif /* NCPUS == 1 */ 6168762Smckusick 6268762Smckusick /* 6368762Smckusick * Acquire a resource. 6468762Smckusick */ 6568762Smckusick #define ACQUIRE(lkp, error, extflags, wanted) \ 6668762Smckusick PAUSE(lkp, wanted); \ 6768762Smckusick for (error = 0; wanted; ) { \ 6868800Smckusick (lkp)->lk_waitcount++; \ 6968933Smckusick simple_unlock(&(lkp)->lk_interlock); \ 7068779Smckusick error = tsleep((void *)lkp, (lkp)->lk_prio, \ 7168779Smckusick (lkp)->lk_wmesg, (lkp)->lk_timo); \ 7268933Smckusick simple_lock(&(lkp)->lk_interlock); \ 7368800Smckusick (lkp)->lk_waitcount--; \ 7468762Smckusick if (error) \ 7568762Smckusick break; \ 7668762Smckusick if ((extflags) & LK_SLEEPFAIL) { \ 7768762Smckusick error = ENOLCK; \ 7868762Smckusick break; \ 7968762Smckusick } \ 8068762Smckusick } 8168762Smckusick 8268762Smckusick /* 8368762Smckusick * Initialize a lock; required before use. 8468762Smckusick */ 8568782Smckusick void 8669387Smckusick lockinit(lkp, prio, wmesg, timo, flags) 8768762Smckusick struct lock *lkp; 8868762Smckusick int prio; 8968762Smckusick char *wmesg; 9068762Smckusick int timo; 9168762Smckusick int flags; 9268762Smckusick { 9369387Smckusick 9468762Smckusick bzero(lkp, sizeof(struct lock)); 9568933Smckusick simple_lock_init(&lkp->lk_interlock); 9668762Smckusick lkp->lk_flags = flags & LK_EXTFLG_MASK; 9768762Smckusick lkp->lk_prio = prio; 9868762Smckusick lkp->lk_timo = timo; 9968762Smckusick lkp->lk_wmesg = wmesg; 10068762Smckusick lkp->lk_lockholder = LK_NOPROC; 10168762Smckusick } 10268762Smckusick 10368762Smckusick /* 10468780Smckusick * Determine the status of a lock. 10568780Smckusick */ 10668780Smckusick int 10768780Smckusick lockstatus(lkp) 10868780Smckusick struct lock *lkp; 10968780Smckusick { 11068780Smckusick int lock_type = 0; 11168780Smckusick 11268933Smckusick simple_lock(&lkp->lk_interlock); 11368780Smckusick if (lkp->lk_exclusivecount != 0) 11468780Smckusick lock_type = LK_EXCLUSIVE; 11568780Smckusick else if (lkp->lk_sharecount != 0) 11668780Smckusick lock_type = LK_SHARED; 11768933Smckusick simple_unlock(&lkp->lk_interlock); 11868780Smckusick return (lock_type); 11968780Smckusick } 12068780Smckusick 12168780Smckusick /* 12268762Smckusick * Set, change, or release a lock. 12368762Smckusick * 12468762Smckusick * Shared requests increment the shared count. Exclusive requests set the 12568762Smckusick * LK_WANT_EXCL flag (preventing further shared locks), and wait for already 12668762Smckusick * accepted shared locks and shared-to-exclusive upgrades to go away. 12768762Smckusick */ 12868782Smckusick int 12969406Smckusick lockmgr(lkp, flags, interlkp, p) 13068945Smckusick __volatile struct lock *lkp; 13168800Smckusick u_int flags; 13269406Smckusick struct simplelock *interlkp; 13369406Smckusick struct proc *p; 13468762Smckusick { 13568779Smckusick int error; 13669406Smckusick pid_t pid; 13769406Smckusick int extflags; 13868762Smckusick 13968800Smckusick error = 0; 14069406Smckusick if (p) 14169406Smckusick pid = p->p_pid; 14269406Smckusick else 14369406Smckusick pid = LK_KERNPROC; 14468933Smckusick simple_lock(&lkp->lk_interlock); 14568945Smckusick if (flags & LK_INTERLOCK) 14668945Smckusick simple_unlock(interlkp); 14768762Smckusick extflags = (flags | lkp->lk_flags) & LK_EXTFLG_MASK; 14869406Smckusick #ifdef DIAGNOSTIC 14969406Smckusick /* 15069406Smckusick * Once a lock has drained, the LK_DRAINING flag is set and an 15169406Smckusick * exclusive lock is returned. The only valid operation thereafter 15269406Smckusick * is a single release of that exclusive lock. This final release 15369406Smckusick * clears the LK_DRAINING flag and sets the LK_DRAINED flag. Any 15469406Smckusick * further requests of any sort will result in a panic. The bits 15569406Smckusick * selected for these two flags are chosen so that they will be set 15669406Smckusick * in memory that is freed (freed memory is filled with 0xdeadbeef). 157*69577Smckusick * The final release is permitted to give a new lease on life to 158*69577Smckusick * the lock by specifying LK_REENABLE. 15969406Smckusick */ 16069406Smckusick if (lkp->lk_flags & (LK_DRAINING|LK_DRAINED)) { 16169406Smckusick if (lkp->lk_flags & LK_DRAINED) 16269406Smckusick panic("lockmgr: using decommissioned lock"); 16369406Smckusick if ((flags & LK_TYPE_MASK) != LK_RELEASE || 16469406Smckusick lkp->lk_lockholder != pid) 16569406Smckusick panic("lockmgr: non-release on draining lock: %d\n", 16669406Smckusick flags & LK_TYPE_MASK); 16769406Smckusick lkp->lk_flags &= ~LK_DRAINING; 168*69577Smckusick if ((flags & LK_REENABLE) == 0) 169*69577Smckusick lkp->lk_flags |= LK_DRAINED; 17069406Smckusick } 17169406Smckusick #endif DIAGNOSTIC 17268762Smckusick 17368762Smckusick switch (flags & LK_TYPE_MASK) { 17468762Smckusick 17568762Smckusick case LK_SHARED: 17668762Smckusick if (lkp->lk_lockholder != pid) { 17768762Smckusick /* 17868762Smckusick * If just polling, check to see if we will block. 17968762Smckusick */ 18068762Smckusick if ((extflags & LK_NOWAIT) && (lkp->lk_flags & 18168762Smckusick (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE))) { 18268800Smckusick error = EBUSY; 18368800Smckusick break; 18468762Smckusick } 18568762Smckusick /* 18668762Smckusick * Wait for exclusive locks and upgrades to clear. 18768762Smckusick */ 18868762Smckusick ACQUIRE(lkp, error, extflags, lkp->lk_flags & 18968762Smckusick (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)); 19068800Smckusick if (error) 19168800Smckusick break; 19268762Smckusick lkp->lk_sharecount++; 19369527Smckusick COUNT(p, 1); 19468800Smckusick break; 19568762Smckusick } 19668762Smckusick /* 19768762Smckusick * We hold an exclusive lock, so downgrade it to shared. 19868762Smckusick * An alternative would be to fail with EDEADLK. 19968762Smckusick */ 20068762Smckusick lkp->lk_sharecount++; 20169527Smckusick COUNT(p, 1); 20268762Smckusick /* fall into downgrade */ 20368762Smckusick 20468762Smckusick case LK_DOWNGRADE: 20568762Smckusick if (lkp->lk_lockholder != pid || lkp->lk_exclusivecount == 0) 20668762Smckusick panic("lockmgr: not holding exclusive lock"); 20768762Smckusick lkp->lk_sharecount += lkp->lk_exclusivecount; 20868762Smckusick lkp->lk_exclusivecount = 0; 20968762Smckusick lkp->lk_flags &= ~LK_HAVE_EXCL; 21068762Smckusick lkp->lk_lockholder = LK_NOPROC; 21168800Smckusick if (lkp->lk_waitcount) 21268779Smckusick wakeup((void *)lkp); 21368800Smckusick break; 21468762Smckusick 21568779Smckusick case LK_EXCLUPGRADE: 21668779Smckusick /* 21768779Smckusick * If another process is ahead of us to get an upgrade, 21868779Smckusick * then we want to fail rather than have an intervening 21968779Smckusick * exclusive access. 22068779Smckusick */ 22168779Smckusick if (lkp->lk_flags & LK_WANT_UPGRADE) { 22268779Smckusick lkp->lk_sharecount--; 22369527Smckusick COUNT(p, -1); 22468800Smckusick error = EBUSY; 22568800Smckusick break; 22668779Smckusick } 22768779Smckusick /* fall into normal upgrade */ 22868779Smckusick 22968762Smckusick case LK_UPGRADE: 23068762Smckusick /* 23168762Smckusick * Upgrade a shared lock to an exclusive one. If another 23268762Smckusick * shared lock has already requested an upgrade to an 23368762Smckusick * exclusive lock, our shared lock is released and an 23468762Smckusick * exclusive lock is requested (which will be granted 23568775Smckusick * after the upgrade). If we return an error, the file 23668775Smckusick * will always be unlocked. 23768762Smckusick */ 23868762Smckusick if (lkp->lk_lockholder == pid || lkp->lk_sharecount <= 0) 23968762Smckusick panic("lockmgr: upgrade exclusive lock"); 24068775Smckusick lkp->lk_sharecount--; 24169527Smckusick COUNT(p, -1); 24268762Smckusick /* 24368762Smckusick * If we are just polling, check to see if we will block. 24468762Smckusick */ 24568762Smckusick if ((extflags & LK_NOWAIT) && 24668762Smckusick ((lkp->lk_flags & LK_WANT_UPGRADE) || 24768762Smckusick lkp->lk_sharecount > 1)) { 24868800Smckusick error = EBUSY; 24968800Smckusick break; 25068762Smckusick } 25168762Smckusick if ((lkp->lk_flags & LK_WANT_UPGRADE) == 0) { 25268762Smckusick /* 25368762Smckusick * We are first shared lock to request an upgrade, so 25468762Smckusick * request upgrade and wait for the shared count to 25568762Smckusick * drop to zero, then take exclusive lock. 25668762Smckusick */ 25768762Smckusick lkp->lk_flags |= LK_WANT_UPGRADE; 25868762Smckusick ACQUIRE(lkp, error, extflags, lkp->lk_sharecount); 25968762Smckusick lkp->lk_flags &= ~LK_WANT_UPGRADE; 26068800Smckusick if (error) 26168800Smckusick break; 26268762Smckusick lkp->lk_flags |= LK_HAVE_EXCL; 26368762Smckusick lkp->lk_lockholder = pid; 26468762Smckusick if (lkp->lk_exclusivecount != 0) 26568762Smckusick panic("lockmgr: non-zero exclusive count"); 26668762Smckusick lkp->lk_exclusivecount = 1; 26769527Smckusick COUNT(p, 1); 26868800Smckusick break; 26968762Smckusick } 27068762Smckusick /* 27168762Smckusick * Someone else has requested upgrade. Release our shared 27268762Smckusick * lock, awaken upgrade requestor if we are the last shared 27368762Smckusick * lock, then request an exclusive lock. 27468762Smckusick */ 27568800Smckusick if (lkp->lk_sharecount == 0 && lkp->lk_waitcount) 27668779Smckusick wakeup((void *)lkp); 27768762Smckusick /* fall into exclusive request */ 27868762Smckusick 27968762Smckusick case LK_EXCLUSIVE: 28069461Smckusick if (lkp->lk_lockholder == pid && pid != LK_KERNPROC) { 28168762Smckusick /* 28268762Smckusick * Recursive lock. 28368762Smckusick */ 28468762Smckusick if ((extflags & LK_CANRECURSE) == 0) 28568762Smckusick panic("lockmgr: locking against myself"); 28668762Smckusick lkp->lk_exclusivecount++; 28769527Smckusick COUNT(p, 1); 28868800Smckusick break; 28968762Smckusick } 29068762Smckusick /* 29168762Smckusick * If we are just polling, check to see if we will sleep. 29268762Smckusick */ 29368762Smckusick if ((extflags & LK_NOWAIT) && ((lkp->lk_flags & 29468762Smckusick (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) || 29568762Smckusick lkp->lk_sharecount != 0)) { 29668800Smckusick error = EBUSY; 29768800Smckusick break; 29868762Smckusick } 29968762Smckusick /* 30068762Smckusick * Try to acquire the want_exclusive flag. 30168762Smckusick */ 30268762Smckusick ACQUIRE(lkp, error, extflags, lkp->lk_flags & 30368762Smckusick (LK_HAVE_EXCL | LK_WANT_EXCL)); 30468800Smckusick if (error) 30568800Smckusick break; 30668762Smckusick lkp->lk_flags |= LK_WANT_EXCL; 30768762Smckusick /* 30868762Smckusick * Wait for shared locks and upgrades to finish. 30968762Smckusick */ 31068762Smckusick ACQUIRE(lkp, error, extflags, lkp->lk_sharecount != 0 || 31168762Smckusick (lkp->lk_flags & LK_WANT_UPGRADE)); 31268762Smckusick lkp->lk_flags &= ~LK_WANT_EXCL; 31368800Smckusick if (error) 31468800Smckusick break; 31568762Smckusick lkp->lk_flags |= LK_HAVE_EXCL; 31668762Smckusick lkp->lk_lockholder = pid; 31768762Smckusick if (lkp->lk_exclusivecount != 0) 31868762Smckusick panic("lockmgr: non-zero exclusive count"); 31968762Smckusick lkp->lk_exclusivecount = 1; 32069527Smckusick COUNT(p, 1); 32168800Smckusick break; 32268762Smckusick 32368762Smckusick case LK_RELEASE: 32468762Smckusick if (lkp->lk_exclusivecount != 0) { 32568800Smckusick if (pid != lkp->lk_lockholder) 32668800Smckusick panic("lockmgr: pid %d, not %s %d unlocking", 32768800Smckusick pid, "exclusive lock holder", 32868800Smckusick lkp->lk_lockholder); 32968762Smckusick lkp->lk_exclusivecount--; 33069527Smckusick COUNT(p, -1); 33168762Smckusick if (lkp->lk_exclusivecount == 0) { 33268762Smckusick lkp->lk_flags &= ~LK_HAVE_EXCL; 33368762Smckusick lkp->lk_lockholder = LK_NOPROC; 33468762Smckusick } 33569527Smckusick } else if (lkp->lk_sharecount != 0) { 33668762Smckusick lkp->lk_sharecount--; 33769527Smckusick COUNT(p, -1); 33869527Smckusick } 33968800Smckusick if (lkp->lk_waitcount) 34068779Smckusick wakeup((void *)lkp); 34168800Smckusick break; 34268800Smckusick 34368800Smckusick case LK_DRAIN: 34468800Smckusick /* 34569406Smckusick * Check that we do not already hold the lock, as it can 34669406Smckusick * never drain if we do. Unfortunately, we have no way to 34769406Smckusick * check for holding a shared lock, but at least we can 34869406Smckusick * check for an exclusive one. 34969406Smckusick */ 35069406Smckusick if (lkp->lk_lockholder == pid) 35169406Smckusick panic("lockmgr: draining against myself"); 35269406Smckusick /* 35368800Smckusick * If we are just polling, check to see if we will sleep. 35468800Smckusick */ 35568800Smckusick if ((extflags & LK_NOWAIT) && ((lkp->lk_flags & 35668800Smckusick (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) || 35768800Smckusick lkp->lk_sharecount != 0 || lkp->lk_waitcount != 0)) { 35868800Smckusick error = EBUSY; 35968800Smckusick break; 36068762Smckusick } 36168800Smckusick PAUSE(lkp, ((lkp->lk_flags & 36268800Smckusick (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) || 36368800Smckusick lkp->lk_sharecount != 0 || lkp->lk_waitcount != 0)); 36468800Smckusick for (error = 0; ((lkp->lk_flags & 36568800Smckusick (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) || 36668800Smckusick lkp->lk_sharecount != 0 || lkp->lk_waitcount != 0); ) { 36768800Smckusick lkp->lk_flags |= LK_WAITDRAIN; 36868933Smckusick simple_unlock(&lkp->lk_interlock); 36968800Smckusick if (error = tsleep((void *)&lkp->lk_flags, lkp->lk_prio, 37068800Smckusick lkp->lk_wmesg, lkp->lk_timo)) 37168800Smckusick return (error); 37268800Smckusick if ((extflags) & LK_SLEEPFAIL) 37368800Smckusick return (ENOLCK); 37468933Smckusick simple_lock(&lkp->lk_interlock); 37568800Smckusick } 37669406Smckusick lkp->lk_flags |= LK_DRAINING | LK_HAVE_EXCL; 37768945Smckusick lkp->lk_lockholder = pid; 37868945Smckusick lkp->lk_exclusivecount = 1; 37969527Smckusick COUNT(p, 1); 38068800Smckusick break; 38168762Smckusick 38268762Smckusick default: 38368933Smckusick simple_unlock(&lkp->lk_interlock); 38468762Smckusick panic("lockmgr: unknown locktype request %d", 38568762Smckusick flags & LK_TYPE_MASK); 38668775Smckusick /* NOTREACHED */ 38768762Smckusick } 38868800Smckusick if ((lkp->lk_flags & LK_WAITDRAIN) && ((lkp->lk_flags & 38968800Smckusick (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE)) == 0 && 39068800Smckusick lkp->lk_sharecount == 0 && lkp->lk_waitcount == 0)) { 39168800Smckusick lkp->lk_flags &= ~LK_WAITDRAIN; 39268800Smckusick wakeup((void *)&lkp->lk_flags); 39368800Smckusick } 39468933Smckusick simple_unlock(&lkp->lk_interlock); 39568800Smckusick return (error); 39668762Smckusick } 39768945Smckusick 39869387Smckusick /* 39969387Smckusick * Print out information about state of a lock. Used by VOP_PRINT 40069387Smckusick * routines to display ststus about contained locks. 40169387Smckusick */ 40268945Smckusick lockmgr_printinfo(lkp) 40368945Smckusick struct lock *lkp; 40468945Smckusick { 40568945Smckusick 40668945Smckusick if (lkp->lk_sharecount) 40768945Smckusick printf(" lock type %s: SHARED", lkp->lk_wmesg); 40868945Smckusick else if (lkp->lk_flags & LK_HAVE_EXCL) 40968945Smckusick printf(" lock type %s: EXCL by pid %d", lkp->lk_wmesg, 41068945Smckusick lkp->lk_lockholder); 41168945Smckusick if (lkp->lk_waitcount > 0) 41268945Smckusick printf(" with %d pending", lkp->lk_waitcount); 41368945Smckusick } 41469387Smckusick 41569387Smckusick #if defined(DEBUG) && NCPUS == 1 41669461Smckusick #include <sys/kernel.h> 41769461Smckusick #include <vm/vm.h> 41869461Smckusick #include <sys/sysctl.h> 41969570Smckusick int lockpausetime = 0; 42069461Smckusick struct ctldebug debug2 = { "lockpausetime", &lockpausetime }; 42169570Smckusick int simplelockrecurse; 42269387Smckusick /* 42369387Smckusick * Simple lock functions so that the debugger can see from whence 42469387Smckusick * they are being called. 42569387Smckusick */ 42669387Smckusick void 42769387Smckusick simple_lock_init(alp) 42869406Smckusick struct simplelock *alp; 42969387Smckusick { 43069387Smckusick 43169387Smckusick alp->lock_data = 0; 43269387Smckusick } 43369387Smckusick 43469387Smckusick void 43569527Smckusick _simple_lock(alp, id, l) 43669406Smckusick __volatile struct simplelock *alp; 43769527Smckusick const char *id; 43869527Smckusick int l; 43969387Smckusick { 44069387Smckusick 44169570Smckusick if (simplelockrecurse) 44269570Smckusick return; 44369461Smckusick if (alp->lock_data == 1) { 44469461Smckusick if (lockpausetime == -1) 44569527Smckusick panic("%s:%d: simple_lock: lock held", id, l); 44669570Smckusick printf("%s:%d: simple_lock: lock held\n", id, l); 44769570Smckusick if (lockpausetime == 1) { 44869536Smckusick BACKTRACE(curproc); 44969570Smckusick } else if (lockpausetime > 1) { 45069527Smckusick printf("%s:%d: simple_lock: lock held...", id, l); 45169461Smckusick tsleep(&lockpausetime, PCATCH | PPAUSE, "slock", 45269461Smckusick lockpausetime * hz); 45369461Smckusick printf(" continuing\n"); 45469461Smckusick } 45569461Smckusick } 45669387Smckusick alp->lock_data = 1; 45769555Spendry if (curproc) 45869555Spendry curproc->p_simple_locks++; 45969387Smckusick } 46069387Smckusick 46169387Smckusick int 46269527Smckusick _simple_lock_try(alp, id, l) 46369406Smckusick __volatile struct simplelock *alp; 46469527Smckusick const char *id; 46569527Smckusick int l; 46669387Smckusick { 46769387Smckusick 46869570Smckusick if (alp->lock_data) 46969570Smckusick return (0); 47069570Smckusick if (simplelockrecurse) 47169570Smckusick return (1); 47269461Smckusick if (alp->lock_data == 1) { 47369461Smckusick if (lockpausetime == -1) 47469527Smckusick panic("%s:%d: simple_lock_try: lock held", id, l); 47569570Smckusick printf("%s:%d: simple_lock_try: lock held\n", id, l); 47669570Smckusick if (lockpausetime == 1) { 47769536Smckusick BACKTRACE(curproc); 47869570Smckusick } else if (lockpausetime > 1) { 47969527Smckusick printf("%s:%d: simple_lock_try: lock held...", id, l); 48069461Smckusick tsleep(&lockpausetime, PCATCH | PPAUSE, "slock", 48169461Smckusick lockpausetime * hz); 48269461Smckusick printf(" continuing\n"); 48369461Smckusick } 48469461Smckusick } 48569387Smckusick alp->lock_data = 1; 48669555Spendry if (curproc) 48769555Spendry curproc->p_simple_locks++; 48869387Smckusick return (1); 48969387Smckusick } 49069387Smckusick 49169387Smckusick void 49269527Smckusick _simple_unlock(alp, id, l) 49369406Smckusick __volatile struct simplelock *alp; 49469527Smckusick const char *id; 49569527Smckusick int l; 49669387Smckusick { 49769387Smckusick 49869570Smckusick if (simplelockrecurse) 49969570Smckusick return; 50069461Smckusick if (alp->lock_data == 0) { 50169461Smckusick if (lockpausetime == -1) 50269527Smckusick panic("%s:%d: simple_unlock: lock not held", id, l); 50369570Smckusick printf("%s:%d: simple_unlock: lock not held\n", id, l); 50469570Smckusick if (lockpausetime == 1) { 50569536Smckusick BACKTRACE(curproc); 50669570Smckusick } else if (lockpausetime > 1) { 50769527Smckusick printf("%s:%d: simple_unlock: lock not held...", id, l); 50869461Smckusick tsleep(&lockpausetime, PCATCH | PPAUSE, "sunlock", 50969461Smckusick lockpausetime * hz); 51069461Smckusick printf(" continuing\n"); 51169461Smckusick } 51269461Smckusick } 51369387Smckusick alp->lock_data = 0; 51469555Spendry if (curproc) 51569555Spendry curproc->p_simple_locks--; 51669387Smckusick } 51769387Smckusick #endif /* DEBUG && NCPUS == 1 */ 518