Linux 2.6.38-rc7
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / include / linux / bit_spinlock.h
blobe612575a259683c2429cd2d1b46a1cc9671d8141
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>
8 /*
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.
23 preempt_disable();
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)) {
27 preempt_enable();
28 cpu_relax();
29 preempt_disable();
32 #endif
33 __acquire(bitlock);
37 * Return true if it was acquired
39 static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
41 preempt_disable();
42 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
43 if (unlikely(test_and_set_bit_lock(bitnum, addr))) {
44 preempt_enable();
45 return 0;
47 #endif
48 __acquire(bitlock);
49 return 1;
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));
59 #endif
60 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
61 clear_bit_unlock(bitnum, addr);
62 #endif
63 preempt_enable();
64 __release(bitlock);
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));
76 #endif
77 #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
78 __clear_bit_unlock(bitnum, addr);
79 #endif
80 preempt_enable();
81 __release(bitlock);
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();
93 #else
94 return 1;
95 #endif
98 #endif /* __LINUX_BIT_SPINLOCK_H */