kern_lock.c (28569) | kern_lock.c (29653) |
---|---|
1/* 2 * Copyright (c) 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Copyright (C) 1997 6 * John S. Dyson. All rights reserved. 7 * 8 * This code contains ideas from software contributed to Berkeley by --- 24 unchanged lines hidden (view full) --- 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)kern_lock.c 8.18 (Berkeley) 5/21/95 | 1/* 2 * Copyright (c) 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Copyright (C) 1997 6 * John S. Dyson. All rights reserved. 7 * 8 * This code contains ideas from software contributed to Berkeley by --- 24 unchanged lines hidden (view full) --- 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 38 * SUCH DAMAGE. 39 * 40 * @(#)kern_lock.c 8.18 (Berkeley) 5/21/95 |
41 * $Id: kern_lock.c,v 1.10 1997/08/19 00:27:07 dyson Exp $ | 41 * $Id: kern_lock.c,v 1.11 1997/08/22 07:16:46 phk Exp $ |
42 */ 43 44#include <sys/param.h> 45#include <sys/proc.h> 46#include <sys/lock.h> 47#include <sys/systm.h> 48 49#ifdef SMP --- 15 unchanged lines hidden (view full) --- 65#define LOCK_SAMPLE_WAIT 7 66 67#if defined(DIAGNOSTIC) 68#define LOCK_INLINE 69#else 70#define LOCK_INLINE inline 71#endif 72 | 42 */ 43 44#include <sys/param.h> 45#include <sys/proc.h> 46#include <sys/lock.h> 47#include <sys/systm.h> 48 49#ifdef SMP --- 15 unchanged lines hidden (view full) --- 65#define LOCK_SAMPLE_WAIT 7 66 67#if defined(DIAGNOSTIC) 68#define LOCK_INLINE 69#else 70#define LOCK_INLINE inline 71#endif 72 |
73#define LK_ALL (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | \ 74 LK_SHARE_NONZERO | LK_WAIT_NONZERO) 75 |
|
73static int acquire(struct lock *lkp, int extflags, int wanted); | 76static int acquire(struct lock *lkp, int extflags, int wanted); |
77static int apause(struct lock *lkp, int flags); 78static int acquiredrain(struct lock *lkp, int extflags) ; |
|
74 75static LOCK_INLINE void 76sharelock(struct lock *lkp, int incr) { 77 lkp->lk_flags |= LK_SHARE_NONZERO; 78 lkp->lk_sharecount += incr; 79} 80 81static LOCK_INLINE void --- 7 unchanged lines hidden (view full) --- 89#endif 90#endif 91 92 lkp->lk_sharecount -= decr; 93 if (lkp->lk_sharecount == 0) 94 lkp->lk_flags &= ~LK_SHARE_NONZERO; 95} 96 | 79 80static LOCK_INLINE void 81sharelock(struct lock *lkp, int incr) { 82 lkp->lk_flags |= LK_SHARE_NONZERO; 83 lkp->lk_sharecount += incr; 84} 85 86static LOCK_INLINE void --- 7 unchanged lines hidden (view full) --- 94#endif 95#endif 96 97 lkp->lk_sharecount -= decr; 98 if (lkp->lk_sharecount == 0) 99 lkp->lk_flags &= ~LK_SHARE_NONZERO; 100} 101 |
102/* 103 * This is the waitloop optimization, and note for this to work 104 * simple_lock and simple_unlock should be subroutines to avoid 105 * optimization troubles. 106 */ |
|
97static int 98apause(struct lock *lkp, int flags) { 99 int lock_wait; 100 lock_wait = LOCK_WAIT_TIME; 101 for (; lock_wait > 0; lock_wait--) { 102 int i; 103 if ((lkp->lk_flags & flags) == 0) 104 return 0; --- 5 unchanged lines hidden (view full) --- 110 return 0; 111 break; 112 } 113 } 114 } 115 return 1; 116} 117 | 107static int 108apause(struct lock *lkp, int flags) { 109 int lock_wait; 110 lock_wait = LOCK_WAIT_TIME; 111 for (; lock_wait > 0; lock_wait--) { 112 int i; 113 if ((lkp->lk_flags & flags) == 0) 114 return 0; --- 5 unchanged lines hidden (view full) --- 120 return 0; 121 break; 122 } 123 } 124 } 125 return 1; 126} 127 |
118 | |
119static int 120acquire(struct lock *lkp, int extflags, int wanted) { 121 int error; 122 int lock_wait; 123 124 if ((extflags & LK_NOWAIT) && (lkp->lk_flags & wanted)) { 125 return EBUSY; 126 } 127 | 128static int 129acquire(struct lock *lkp, int extflags, int wanted) { 130 int error; 131 int lock_wait; 132 133 if ((extflags & LK_NOWAIT) && (lkp->lk_flags & wanted)) { 134 return EBUSY; 135 } 136 |
128 error = apause(lkp, wanted); 129 if (error == 0) 130 return 0; | 137 if (((lkp->lk_flags | extflags) & LK_NOPAUSE) == 0) { 138 error = apause(lkp, wanted); 139 if (error == 0) 140 return 0; 141 } |
131 132 while ((lkp->lk_flags & wanted) != 0) { 133 lkp->lk_flags |= LK_WAIT_NONZERO; 134 lkp->lk_waitcount++; 135 simple_unlock(&lkp->lk_interlock); 136 error = tsleep(lkp, lkp->lk_prio, lkp->lk_wmesg, lkp->lk_timo); 137 simple_lock(&lkp->lk_interlock); 138 lkp->lk_waitcount--; 139 if (lkp->lk_waitcount == 0) 140 lkp->lk_flags &= ~LK_WAIT_NONZERO; 141 if (error) 142 return error; 143 if (extflags & LK_SLEEPFAIL) { 144 return ENOLCK; 145 } 146 } 147 return 0; 148} 149 | 142 143 while ((lkp->lk_flags & wanted) != 0) { 144 lkp->lk_flags |= LK_WAIT_NONZERO; 145 lkp->lk_waitcount++; 146 simple_unlock(&lkp->lk_interlock); 147 error = tsleep(lkp, lkp->lk_prio, lkp->lk_wmesg, lkp->lk_timo); 148 simple_lock(&lkp->lk_interlock); 149 lkp->lk_waitcount--; 150 if (lkp->lk_waitcount == 0) 151 lkp->lk_flags &= ~LK_WAIT_NONZERO; 152 if (error) 153 return error; 154 if (extflags & LK_SLEEPFAIL) { 155 return ENOLCK; 156 } 157 } 158 return 0; 159} 160 |
150#define LK_ALL (LK_HAVE_EXCL | LK_WANT_EXCL | LK_WANT_UPGRADE | \ 151 LK_SHARE_NONZERO | LK_WAIT_NONZERO) 152 153static int 154acquiredrain(struct lock *lkp, int extflags) { 155 int error; 156 int lock_wait; 157 158 if ((extflags & LK_NOWAIT) && (lkp->lk_flags & LK_ALL)) { 159 return EBUSY; 160 } 161 162 error = apause(lkp, LK_ALL); 163 if (error == 0) 164 return 0; 165 166 while (lkp->lk_flags & LK_ALL) { 167 lkp->lk_flags |= LK_WAITDRAIN; 168 simple_unlock(&lkp->lk_interlock); 169 error = tsleep(&lkp->lk_flags, lkp->lk_prio, 170 lkp->lk_wmesg, lkp->lk_timo); 171 simple_lock(&lkp->lk_interlock); 172 if (error) 173 return error; 174 if (extflags & LK_SLEEPFAIL) { 175 return ENOLCK; 176 } 177 } 178 return 0; 179} 180 | |
181/* | 161/* |
182 * Initialize a lock; required before use. 183 */ 184void 185lockinit(lkp, prio, wmesg, timo, flags) 186 struct lock *lkp; 187 int prio; 188 char *wmesg; 189 int timo; 190 int flags; 191{ 192 193 simple_lock_init(&lkp->lk_interlock); 194 lkp->lk_flags = (flags & LK_EXTFLG_MASK); 195 lkp->lk_sharecount = 0; 196 lkp->lk_waitcount = 0; 197 lkp->lk_exclusivecount = 0; 198 lkp->lk_prio = prio; 199 lkp->lk_wmesg = wmesg; 200 lkp->lk_timo = timo; 201 lkp->lk_lockholder = LK_NOPROC; 202} 203 204/* 205 * Determine the status of a lock. 206 */ 207int 208lockstatus(lkp) 209 struct lock *lkp; 210{ 211 int lock_type = 0; 212 213 simple_lock(&lkp->lk_interlock); 214 if (lkp->lk_exclusivecount != 0) 215 lock_type = LK_EXCLUSIVE; 216 else if (lkp->lk_sharecount != 0) 217 lock_type = LK_SHARED; 218 simple_unlock(&lkp->lk_interlock); 219 return (lock_type); 220} 221 222/* | |
223 * Set, change, or release a lock. 224 * 225 * Shared requests increment the shared count. Exclusive requests set the 226 * LK_WANT_EXCL flag (preventing further shared locks), and wait for already 227 * accepted shared locks and shared-to-exclusive upgrades to go away. 228 */ 229int 230lockmgr(lkp, flags, interlkp, p) --- 205 unchanged lines hidden (view full) --- 436 LK_SHARE_NONZERO | LK_WAIT_NONZERO)) == 0) { 437 lkp->lk_flags &= ~LK_WAITDRAIN; 438 wakeup((void *)&lkp->lk_flags); 439 } 440 simple_unlock(&lkp->lk_interlock); 441 return (error); 442} 443 | 162 * Set, change, or release a lock. 163 * 164 * Shared requests increment the shared count. Exclusive requests set the 165 * LK_WANT_EXCL flag (preventing further shared locks), and wait for already 166 * accepted shared locks and shared-to-exclusive upgrades to go away. 167 */ 168int 169lockmgr(lkp, flags, interlkp, p) --- 205 unchanged lines hidden (view full) --- 375 LK_SHARE_NONZERO | LK_WAIT_NONZERO)) == 0) { 376 lkp->lk_flags &= ~LK_WAITDRAIN; 377 wakeup((void *)&lkp->lk_flags); 378 } 379 simple_unlock(&lkp->lk_interlock); 380 return (error); 381} 382 |
383static int 384acquiredrain(struct lock *lkp, int extflags) { 385 int error; 386 int lock_wait; 387 388 if ((extflags & LK_NOWAIT) && (lkp->lk_flags & LK_ALL)) { 389 return EBUSY; 390 } 391 392 error = apause(lkp, LK_ALL); 393 if (error == 0) 394 return 0; 395 396 while (lkp->lk_flags & LK_ALL) { 397 lkp->lk_flags |= LK_WAITDRAIN; 398 simple_unlock(&lkp->lk_interlock); 399 error = tsleep(&lkp->lk_flags, lkp->lk_prio, 400 lkp->lk_wmesg, lkp->lk_timo); 401 simple_lock(&lkp->lk_interlock); 402 if (error) 403 return error; 404 if (extflags & LK_SLEEPFAIL) { 405 return ENOLCK; 406 } 407 } 408 return 0; 409} 410 |
|
444/* | 411/* |
412 * Initialize a lock; required before use. 413 */ 414void 415lockinit(lkp, prio, wmesg, timo, flags) 416 struct lock *lkp; 417 int prio; 418 char *wmesg; 419 int timo; 420 int flags; 421{ 422 423 simple_lock_init(&lkp->lk_interlock); 424 lkp->lk_flags = (flags & LK_EXTFLG_MASK); 425 lkp->lk_sharecount = 0; 426 lkp->lk_waitcount = 0; 427 lkp->lk_exclusivecount = 0; 428 lkp->lk_prio = prio; 429 lkp->lk_wmesg = wmesg; 430 lkp->lk_timo = timo; 431 lkp->lk_lockholder = LK_NOPROC; 432} 433 434/* 435 * Determine the status of a lock. 436 */ 437int 438lockstatus(lkp) 439 struct lock *lkp; 440{ 441 int lock_type = 0; 442 443 simple_lock(&lkp->lk_interlock); 444 if (lkp->lk_exclusivecount != 0) 445 lock_type = LK_EXCLUSIVE; 446 else if (lkp->lk_sharecount != 0) 447 lock_type = LK_SHARED; 448 simple_unlock(&lkp->lk_interlock); 449 return (lock_type); 450} 451 452/* |
|
445 * Print out information about state of a lock. Used by VOP_PRINT 446 * routines to display status about contained locks. 447 */ 448void 449lockmgr_printinfo(lkp) 450 struct lock *lkp; 451{ 452 --- 104 unchanged lines hidden --- | 453 * Print out information about state of a lock. Used by VOP_PRINT 454 * routines to display status about contained locks. 455 */ 456void 457lockmgr_printinfo(lkp) 458 struct lock *lkp; 459{ 460 --- 104 unchanged lines hidden --- |