Line data Source code
1 : #ifndef __LINUX_BIT_SPINLOCK_H
2 : #define __LINUX_BIT_SPINLOCK_H
3 :
4 : /*
5 : * bit-based spin_lock()
6 : *
7 : * Don't use this unless you really need to: spin_lock() and spin_unlock()
8 : * are significantly faster.
9 : */
10 : static inline void bit_spin_lock(int bitnum, unsigned long *addr)
11 : {
12 0 : /*
13 0 : * Assuming the lock is uncontended, this never enters
14 0 : * the body of the outer loop. If it is contended, then
15 : * within the inner loop a non-atomic test is used to
16 : * busywait with less bus contention for a good time to
17 : * attempt to acquire the lock bit.
18 : */
19 : preempt_disable();
20 : #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
21 0 : while (unlikely(test_and_set_bit_lock(bitnum, addr))) {
22 0 : while (test_bit(bitnum, addr)) {
23 0 : preempt_enable();
24 0 : cpu_relax();
25 : preempt_disable();
26 0 : }
27 : }
28 : #endif
29 0 : __acquire(bitlock);
30 0 : }
31 :
32 : /*
33 : * Return true if it was acquired
34 : */
35 : static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
36 : {
37 0 : preempt_disable();
38 0 : #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
39 0 : if (unlikely(test_and_set_bit_lock(bitnum, addr))) {
40 : preempt_enable();
41 0 : return 0;
42 : }
43 : #endif
44 : __acquire(bitlock);
45 0 : return 1;
46 : }
47 :
48 : /*
49 : * bit-based spin_unlock()
50 : */
51 : static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
52 : {
53 : #ifdef CONFIG_DEBUG_SPINLOCK
54 : BUG_ON(!test_bit(bitnum, addr));
55 : #endif
56 : #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
57 0 : clear_bit_unlock(bitnum, addr);
58 : #endif
59 : preempt_enable();
60 : __release(bitlock);
61 0 : }
62 :
63 : /*
64 : * bit-based spin_unlock()
65 : * non-atomic version, which can be used eg. if the bit lock itself is
66 : * protecting the rest of the flags in the word.
67 : */
68 : static inline void __bit_spin_unlock(int bitnum, unsigned long *addr)
69 : {
70 : #ifdef CONFIG_DEBUG_SPINLOCK
71 : BUG_ON(!test_bit(bitnum, addr));
72 : #endif
73 : #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
74 : __clear_bit_unlock(bitnum, addr);
75 : #endif
76 : preempt_enable();
77 : __release(bitlock);
78 : }
79 :
80 : /*
81 : * Return true if the lock is held.
82 : */
83 : static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
84 : {
85 0 : #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
86 0 : return test_bit(bitnum, addr);
87 : #elif defined CONFIG_PREEMPT
88 : return preempt_count();
89 : #else
90 : return 1;
91 : #endif
92 : }
93 :
94 : #endif /* __LINUX_BIT_SPINLOCK_H */
95 :
|