kern_rwlock.c (167801) | kern_rwlock.c (168073) |
---|---|
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 167801 2007-03-22 16:09:23Z jhb $"); | 35__FBSDID("$FreeBSD: head/sys/kern/kern_rwlock.c 168073 2007-03-30 18:08:55Z jhb $"); |
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/lock.h> 43#include <sys/mutex.h> --- 432 unchanged lines hidden (view full) --- 476 477 /* 478 * If the lock was released by a writer with both readers 479 * and writers waiting and a reader hasn't woken up and 480 * acquired the lock yet, rw_lock will be set to the 481 * value RW_UNLOCKED | RW_LOCK_WRITE_WAITERS. If we see 482 * that value, try to acquire it once. Note that we have 483 * to preserve the RW_LOCK_WRITE_WAITERS flag as there are | 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/lock.h> 43#include <sys/mutex.h> --- 432 unchanged lines hidden (view full) --- 476 477 /* 478 * If the lock was released by a writer with both readers 479 * and writers waiting and a reader hasn't woken up and 480 * acquired the lock yet, rw_lock will be set to the 481 * value RW_UNLOCKED | RW_LOCK_WRITE_WAITERS. If we see 482 * that value, try to acquire it once. Note that we have 483 * to preserve the RW_LOCK_WRITE_WAITERS flag as there are |
484 * other writers waiting still. If we fail, restart the | 484 * other writers waiting still. If we fail, restart the |
485 * loop. 486 */ 487 if (v == (RW_UNLOCKED | RW_LOCK_WRITE_WAITERS)) { 488 if (atomic_cmpset_acq_ptr(&rw->rw_lock, 489 RW_UNLOCKED | RW_LOCK_WRITE_WAITERS, 490 tid | RW_LOCK_WRITE_WAITERS)) { 491 turnstile_claim(&rw->lock_object); 492 CTR2(KTR_LOCK, "%s: %p claimed by new writer", --- 170 unchanged lines hidden (view full) --- 663 * Attempt to switch from one reader to a writer. If there 664 * are any write waiters, then we will have to lock the 665 * turnstile first to prevent races with another writer 666 * calling turnstile_wait() before we have claimed this 667 * turnstile. So, do the simple case of no waiters first. 668 */ 669 tid = (uintptr_t)curthread; 670 if (!(rw->rw_lock & RW_LOCK_WRITE_WAITERS)) { | 485 * loop. 486 */ 487 if (v == (RW_UNLOCKED | RW_LOCK_WRITE_WAITERS)) { 488 if (atomic_cmpset_acq_ptr(&rw->rw_lock, 489 RW_UNLOCKED | RW_LOCK_WRITE_WAITERS, 490 tid | RW_LOCK_WRITE_WAITERS)) { 491 turnstile_claim(&rw->lock_object); 492 CTR2(KTR_LOCK, "%s: %p claimed by new writer", --- 170 unchanged lines hidden (view full) --- 663 * Attempt to switch from one reader to a writer. If there 664 * are any write waiters, then we will have to lock the 665 * turnstile first to prevent races with another writer 666 * calling turnstile_wait() before we have claimed this 667 * turnstile. So, do the simple case of no waiters first. 668 */ 669 tid = (uintptr_t)curthread; 670 if (!(rw->rw_lock & RW_LOCK_WRITE_WAITERS)) { |
671 success = atomic_cmpset_acq_ptr(&rw->rw_lock, 672 RW_READERS_LOCK(1), tid); | 671 success = atomic_cmpset_ptr(&rw->rw_lock, RW_READERS_LOCK(1), 672 tid); |
673 goto out; 674 } 675 676 /* 677 * Ok, we think we have write waiters, so lock the 678 * turnstile. 679 */ 680 turnstile_lock(&rw->lock_object); 681 682 /* 683 * Try to switch from one reader to a writer again. This time 684 * we honor the current state of the RW_LOCK_WRITE_WAITERS 685 * flag. If we obtain the lock with the flag set, then claim 686 * ownership of the turnstile. In the ADAPTIVE_RWLOCKS case 687 * it is possible for there to not be an associated turnstile 688 * even though there are waiters if all of the waiters are 689 * spinning. 690 */ 691 v = rw->rw_lock & RW_LOCK_WRITE_WAITERS; | 673 goto out; 674 } 675 676 /* 677 * Ok, we think we have write waiters, so lock the 678 * turnstile. 679 */ 680 turnstile_lock(&rw->lock_object); 681 682 /* 683 * Try to switch from one reader to a writer again. This time 684 * we honor the current state of the RW_LOCK_WRITE_WAITERS 685 * flag. If we obtain the lock with the flag set, then claim 686 * ownership of the turnstile. In the ADAPTIVE_RWLOCKS case 687 * it is possible for there to not be an associated turnstile 688 * even though there are waiters if all of the waiters are 689 * spinning. 690 */ 691 v = rw->rw_lock & RW_LOCK_WRITE_WAITERS; |
692 success = atomic_cmpset_acq_ptr(&rw->rw_lock, RW_READERS_LOCK(1) | v, | 692 success = atomic_cmpset_ptr(&rw->rw_lock, RW_READERS_LOCK(1) | v, |
693 tid | v); 694#ifdef ADAPTIVE_RWLOCKS 695 if (success && v && turnstile_lookup(&rw->lock_object) != NULL) 696#else 697 if (success && v) 698#endif 699 turnstile_claim(&rw->lock_object); 700 else --- 179 unchanged lines hidden --- | 693 tid | v); 694#ifdef ADAPTIVE_RWLOCKS 695 if (success && v && turnstile_lookup(&rw->lock_object) != NULL) 696#else 697 if (success && v) 698#endif 699 turnstile_claim(&rw->lock_object); 700 else --- 179 unchanged lines hidden --- |