diff options
author | Nick Piggin <npiggin@suse.de> | 2007-10-18 14:06:54 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-19 01:37:29 +0400 |
commit | b8dc93cbe91324b922395919cd5df4cca2fe55f6 (patch) | |
tree | 724a8813d6b5119619a6b8c499a59825575ae0c9 /include/linux/bit_spinlock.h | |
parent | 66ffb04ca5ec43ca763e8a9802ca3244f5519ae1 (diff) | |
download | linux-b8dc93cbe91324b922395919cd5df4cca2fe55f6.tar.xz |
bit_spin_lock: use lock bitops
Convert bit_spin_lock to new locking bitops. Slub can use the non-atomic
store version to clear (Christoph?)
Signed-off-by: Nick Piggin <npiggin@suse.de>
Cc: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/bit_spinlock.h')
-rw-r--r-- | include/linux/bit_spinlock.h | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h index 6b20af0bbb79..7113a32a86ea 100644 --- a/include/linux/bit_spinlock.h +++ b/include/linux/bit_spinlock.h @@ -18,7 +18,7 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr) */ preempt_disable(); #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - while (test_and_set_bit(bitnum, addr)) { + while (unlikely(test_and_set_bit_lock(bitnum, addr))) { while (test_bit(bitnum, addr)) { preempt_enable(); cpu_relax(); @@ -36,7 +36,7 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) { preempt_disable(); #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - if (test_and_set_bit(bitnum, addr)) { + if (unlikely(test_and_set_bit_lock(bitnum, addr))) { preempt_enable(); return 0; } @@ -50,10 +50,28 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) */ static inline void bit_spin_unlock(int bitnum, unsigned long *addr) { +#ifdef CONFIG_DEBUG_SPINLOCK + BUG_ON(!test_bit(bitnum, addr)); +#endif #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) + clear_bit_unlock(bitnum, addr); +#endif + preempt_enable(); + __release(bitlock); +} + +/* + * bit-based spin_unlock() + * non-atomic version, which can be used eg. if the bit lock itself is + * protecting the rest of the flags in the word. + */ +static inline void __bit_spin_unlock(int bitnum, unsigned long *addr) +{ +#ifdef CONFIG_DEBUG_SPINLOCK BUG_ON(!test_bit(bitnum, addr)); - smp_mb__before_clear_bit(); - clear_bit(bitnum, addr); +#endif +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) + __clear_bit_unlock(bitnum, addr); #endif preempt_enable(); __release(bitlock); |