1 #ifndef __LINUX_BIT_SPINLOCK_H
2 #define __LINUX_BIT_SPINLOCK_H
4 #include <linux/kernel.h>
5 #include <linux/preempt.h>
6 #include <asm/atomic.h>
9 * bit-based spin_lock()
11 * Don't use this unless you really need to: spin_lock() and spin_unlock()
12 * are significantly faster.
14 static inline void bit_spin_lock(int bitnum
, unsigned long *addr
)
17 * Assuming the lock is uncontended, this never enters
18 * the body of the outer loop. If it is contended, then
19 * within the inner loop a non-atomic test is used to
20 * busywait with less bus contention for a good time to
21 * attempt to acquire the lock bit.
24 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
25 while (unlikely(test_and_set_bit_lock(bitnum
, addr
))) {
26 while (test_bit(bitnum
, addr
)) {
37 * Return true if it was acquired
39 static inline int bit_spin_trylock(int bitnum
, unsigned long *addr
)
42 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
43 if (unlikely(test_and_set_bit_lock(bitnum
, addr
))) {
53 * bit-based spin_unlock()
55 static inline void bit_spin_unlock(int bitnum
, unsigned long *addr
)
57 #ifdef CONFIG_DEBUG_SPINLOCK
58 BUG_ON(!test_bit(bitnum
, addr
));
60 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
61 clear_bit_unlock(bitnum
, addr
);
68 * bit-based spin_unlock()
69 * non-atomic version, which can be used eg. if the bit lock itself is
70 * protecting the rest of the flags in the word.
72 static inline void __bit_spin_unlock(int bitnum
, unsigned long *addr
)
74 #ifdef CONFIG_DEBUG_SPINLOCK
75 BUG_ON(!test_bit(bitnum
, addr
));
77 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
78 __clear_bit_unlock(bitnum
, addr
);
85 * Return true if the lock is held.
87 static inline int bit_spin_is_locked(int bitnum
, unsigned long *addr
)
89 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
90 return test_bit(bitnum
, addr
);
91 #elif defined CONFIG_PREEMPT
92 return preempt_count();
98 #endif /* __LINUX_BIT_SPINLOCK_H */