Deleted Added
full compact
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 ---