X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=include%2Flinux%2Fbit_spinlock.h;h=7113a32a86ea9fd8816a32625197c8fa3700d2f2;hb=455434d450a358ac5bcf3fc58f8913d13c544622;hp=6b20af0bbb79d2037cfb3c5aa69d6b3cac2f2e59;hpb=2b8dfec8c8fa4ba5bc946a602e94e99861462cad;p=linux-2.6-omap-h63xx.git diff --git a/include/linux/bit_spinlock.h b/include/linux/bit_spinlock.h index 6b20af0bbb7..7113a32a86e 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);