kern_rwlock.c (177843) | kern_rwlock.c (177912) |
---|---|
1/*- 2 * Copyright (c) 2006 John Baldwin <jhb@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 18 unchanged lines hidden (view full) --- 27 * SUCH DAMAGE. 28 */ 29 30/* 31 * Machine independent bits of reader/writer lock implementation. 32 */ 33 34#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2006 John Baldwin <jhb@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 18 unchanged lines hidden (view full) --- 27 * SUCH DAMAGE. 28 */ 29 30/* 31 * Machine independent bits of reader/writer lock implementation. 32 */ 33 34#include <sys/cdefs.h> |
35__FBSDID("$FreeBSD: head/sys/kern/kern_rwlock.c 177843 2008-04-01 20:31:55Z attilio $"); | 35__FBSDID("$FreeBSD: head/sys/kern/kern_rwlock.c 177912 2008-04-04 10:00:46Z jeff $"); |
36 37#include "opt_ddb.h" 38#include "opt_no_adaptive_rwlocks.h" 39 40#include <sys/param.h> 41#include <sys/ktr.h> | 36 37#include "opt_ddb.h" 38#include "opt_no_adaptive_rwlocks.h" 39 40#include <sys/param.h> 41#include <sys/ktr.h> |
42#include <sys/kernel.h> |
|
42#include <sys/lock.h> 43#include <sys/mutex.h> 44#include <sys/proc.h> 45#include <sys/rwlock.h> | 43#include <sys/lock.h> 44#include <sys/mutex.h> 45#include <sys/proc.h> 46#include <sys/rwlock.h> |
47#include <sys/sysctl.h> |
|
46#include <sys/systm.h> 47#include <sys/turnstile.h> 48 49#include <machine/cpu.h> 50 51CTASSERT((RW_RECURSE & LO_CLASSFLAGS) == RW_RECURSE); 52 53#if defined(SMP) && !defined(NO_ADAPTIVE_RWLOCKS) 54#define ADAPTIVE_RWLOCKS 55#endif 56 | 48#include <sys/systm.h> 49#include <sys/turnstile.h> 50 51#include <machine/cpu.h> 52 53CTASSERT((RW_RECURSE & LO_CLASSFLAGS) == RW_RECURSE); 54 55#if defined(SMP) && !defined(NO_ADAPTIVE_RWLOCKS) 56#define ADAPTIVE_RWLOCKS 57#endif 58 |
59#ifdef ADAPTIVE_RWLOCKS 60static int rowner_retries = 10; 61static int rowner_loops = 10000; 62SYSCTL_NODE(_debug, OID_AUTO, rwlock, CTLFLAG_RD, NULL, "rwlock debugging"); 63SYSCTL_INT(_debug_rwlock, OID_AUTO, retry, CTLFLAG_RW, &rowner_retries, 0, ""); 64SYSCTL_INT(_debug_rwlock, OID_AUTO, loops, CTLFLAG_RW, &rowner_loops, 0, ""); 65#endif 66 |
|
57#ifdef DDB 58#include <ddb/ddb.h> 59 60static void db_show_rwlock(struct lock_object *lock); 61#endif 62static void assert_rw(struct lock_object *lock, int what); 63static void lock_rw(struct lock_object *lock, int how); 64static int unlock_rw(struct lock_object *lock); --- 191 unchanged lines hidden (view full) --- 256 RW_LOCK_READ) 257 258void 259_rw_rlock(struct rwlock *rw, const char *file, int line) 260{ 261 struct turnstile *ts; 262#ifdef ADAPTIVE_RWLOCKS 263 volatile struct thread *owner; | 67#ifdef DDB 68#include <ddb/ddb.h> 69 70static void db_show_rwlock(struct lock_object *lock); 71#endif 72static void assert_rw(struct lock_object *lock, int what); 73static void lock_rw(struct lock_object *lock, int how); 74static int unlock_rw(struct lock_object *lock); --- 191 unchanged lines hidden (view full) --- 266 RW_LOCK_READ) 267 268void 269_rw_rlock(struct rwlock *rw, const char *file, int line) 270{ 271 struct turnstile *ts; 272#ifdef ADAPTIVE_RWLOCKS 273 volatile struct thread *owner; |
274 int spintries = 0; 275 int i; |
|
264#endif 265 uint64_t waittime = 0; 266 int contested = 0; 267 uintptr_t v; 268 269 KASSERT(rw->rw_lock != RW_DESTROYED, 270 ("rw_rlock() of destroyed rwlock @ %s:%d", file, line)); 271 KASSERT(rw_wowner(rw) != curthread, --- 47 unchanged lines hidden (view full) --- 319 CTR3(KTR_LOCK, 320 "%s: spinning on %p held by %p", 321 __func__, rw, owner); 322 while ((struct thread*)RW_OWNER(rw->rw_lock) == 323 owner && TD_IS_RUNNING(owner)) 324 cpu_spinwait(); 325 continue; 326 } | 276#endif 277 uint64_t waittime = 0; 278 int contested = 0; 279 uintptr_t v; 280 281 KASSERT(rw->rw_lock != RW_DESTROYED, 282 ("rw_rlock() of destroyed rwlock @ %s:%d", file, line)); 283 KASSERT(rw_wowner(rw) != curthread, --- 47 unchanged lines hidden (view full) --- 331 CTR3(KTR_LOCK, 332 "%s: spinning on %p held by %p", 333 __func__, rw, owner); 334 while ((struct thread*)RW_OWNER(rw->rw_lock) == 335 owner && TD_IS_RUNNING(owner)) 336 cpu_spinwait(); 337 continue; 338 } |
339 } else if (spintries < rowner_retries) { 340 spintries++; 341 for (i = 0; i < rowner_loops; i++) { 342 v = rw->rw_lock; 343 if ((v & RW_LOCK_READ) == 0 || RW_CAN_READ(v)) 344 break; 345 cpu_spinwait(); 346 } 347 if (i != rowner_loops) 348 continue; |
|
327 } 328#endif 329 330 /* 331 * Okay, now it's the hard case. Some other thread already 332 * has a write lock or there are write waiters present, 333 * acquire the turnstile lock so we can begin the process 334 * of blocking. --- 252 unchanged lines hidden (view full) --- 587 if (LOCK_LOG_TEST(&rw->lock_object, 0)) 588 CTR3(KTR_LOCK, "%s: spinning on %p held by %p", 589 __func__, rw, owner); 590 while ((struct thread*)RW_OWNER(rw->rw_lock) == owner && 591 TD_IS_RUNNING(owner)) 592 cpu_spinwait(); 593 continue; 594 } | 349 } 350#endif 351 352 /* 353 * Okay, now it's the hard case. Some other thread already 354 * has a write lock or there are write waiters present, 355 * acquire the turnstile lock so we can begin the process 356 * of blocking. --- 252 unchanged lines hidden (view full) --- 609 if (LOCK_LOG_TEST(&rw->lock_object, 0)) 610 CTR3(KTR_LOCK, "%s: spinning on %p held by %p", 611 __func__, rw, owner); 612 while ((struct thread*)RW_OWNER(rw->rw_lock) == owner && 613 TD_IS_RUNNING(owner)) 614 cpu_spinwait(); 615 continue; 616 } |
595 if ((v & RW_LOCK_READ) && RW_READERS(v) && spintries < 100) { | 617 if ((v & RW_LOCK_READ) && RW_READERS(v) && 618 spintries < rowner_retries) { |
596 if (!(v & RW_LOCK_WRITE_SPINNER)) { 597 if (!atomic_cmpset_ptr(&rw->rw_lock, v, 598 v | RW_LOCK_WRITE_SPINNER)) { 599 cpu_spinwait(); 600 continue; 601 } 602 } 603 spintries++; | 619 if (!(v & RW_LOCK_WRITE_SPINNER)) { 620 if (!atomic_cmpset_ptr(&rw->rw_lock, v, 621 v | RW_LOCK_WRITE_SPINNER)) { 622 cpu_spinwait(); 623 continue; 624 } 625 } 626 spintries++; |
604 for (i = 100000; i > 0; i--) { | 627 for (i = 0; i < rowner_loops; i++) { |
605 if ((rw->rw_lock & RW_LOCK_WRITE_SPINNER) == 0) 606 break; 607 cpu_spinwait(); 608 } | 628 if ((rw->rw_lock & RW_LOCK_WRITE_SPINNER) == 0) 629 break; 630 cpu_spinwait(); 631 } |
609 if (i) | 632 if (i != rowner_loops) |
610 continue; 611 } 612#endif 613 ts = turnstile_trywait(&rw->lock_object); 614 v = rw->rw_lock; 615 616#ifdef ADAPTIVE_RWLOCKS 617 /* --- 388 unchanged lines hidden --- | 633 continue; 634 } 635#endif 636 ts = turnstile_trywait(&rw->lock_object); 637 v = rw->rw_lock; 638 639#ifdef ADAPTIVE_RWLOCKS 640 /* --- 388 unchanged lines hidden --- |