]>
Commit | Line | Data |
---|---|---|
6b6b4792 TG |
1 | #ifndef __LINUX_RWLOCK_API_SMP_H |
2 | #define __LINUX_RWLOCK_API_SMP_H | |
3 | ||
4 | #ifndef __LINUX_SPINLOCK_API_SMP_H | |
5 | # error "please don't include this file directly" | |
6 | #endif | |
7 | ||
8 | /* | |
9 | * include/linux/rwlock_api_smp.h | |
10 | * | |
11 | * spinlock API declarations on SMP (and debug) | |
12 | * (implemented in kernel/spinlock.c) | |
13 | * | |
14 | * portions Copyright 2005, Red Hat, Inc., Ingo Molnar | |
15 | * Released under the General Public License (GPL). | |
16 | */ | |
17 | ||
18 | void __lockfunc _read_lock(rwlock_t *lock) __acquires(lock); | |
19 | void __lockfunc _write_lock(rwlock_t *lock) __acquires(lock); | |
20 | void __lockfunc _read_lock_bh(rwlock_t *lock) __acquires(lock); | |
21 | void __lockfunc _write_lock_bh(rwlock_t *lock) __acquires(lock); | |
22 | void __lockfunc _read_lock_irq(rwlock_t *lock) __acquires(lock); | |
23 | void __lockfunc _write_lock_irq(rwlock_t *lock) __acquires(lock); | |
24 | unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock) | |
25 | __acquires(lock); | |
26 | unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock) | |
27 | __acquires(lock); | |
28 | int __lockfunc _read_trylock(rwlock_t *lock); | |
29 | int __lockfunc _write_trylock(rwlock_t *lock); | |
30 | void __lockfunc _read_unlock(rwlock_t *lock) __releases(lock); | |
31 | void __lockfunc _write_unlock(rwlock_t *lock) __releases(lock); | |
32 | void __lockfunc _read_unlock_bh(rwlock_t *lock) __releases(lock); | |
33 | void __lockfunc _write_unlock_bh(rwlock_t *lock) __releases(lock); | |
34 | void __lockfunc _read_unlock_irq(rwlock_t *lock) __releases(lock); | |
35 | void __lockfunc _write_unlock_irq(rwlock_t *lock) __releases(lock); | |
36 | void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) | |
37 | __releases(lock); | |
38 | void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags) | |
39 | __releases(lock); | |
40 | ||
41 | #ifdef CONFIG_INLINE_READ_LOCK | |
42 | #define _read_lock(lock) __read_lock(lock) | |
43 | #endif | |
44 | ||
45 | #ifdef CONFIG_INLINE_WRITE_LOCK | |
46 | #define _write_lock(lock) __write_lock(lock) | |
47 | #endif | |
48 | ||
49 | #ifdef CONFIG_INLINE_READ_LOCK_BH | |
50 | #define _read_lock_bh(lock) __read_lock_bh(lock) | |
51 | #endif | |
52 | ||
53 | #ifdef CONFIG_INLINE_WRITE_LOCK_BH | |
54 | #define _write_lock_bh(lock) __write_lock_bh(lock) | |
55 | #endif | |
56 | ||
57 | #ifdef CONFIG_INLINE_READ_LOCK_IRQ | |
58 | #define _read_lock_irq(lock) __read_lock_irq(lock) | |
59 | #endif | |
60 | ||
61 | #ifdef CONFIG_INLINE_WRITE_LOCK_IRQ | |
62 | #define _write_lock_irq(lock) __write_lock_irq(lock) | |
63 | #endif | |
64 | ||
65 | #ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE | |
66 | #define _read_lock_irqsave(lock) __read_lock_irqsave(lock) | |
67 | #endif | |
68 | ||
69 | #ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE | |
70 | #define _write_lock_irqsave(lock) __write_lock_irqsave(lock) | |
71 | #endif | |
72 | ||
73 | #ifdef CONFIG_INLINE_READ_TRYLOCK | |
74 | #define _read_trylock(lock) __read_trylock(lock) | |
75 | #endif | |
76 | ||
77 | #ifdef CONFIG_INLINE_WRITE_TRYLOCK | |
78 | #define _write_trylock(lock) __write_trylock(lock) | |
79 | #endif | |
80 | ||
81 | #ifdef CONFIG_INLINE_READ_UNLOCK | |
82 | #define _read_unlock(lock) __read_unlock(lock) | |
83 | #endif | |
84 | ||
85 | #ifdef CONFIG_INLINE_WRITE_UNLOCK | |
86 | #define _write_unlock(lock) __write_unlock(lock) | |
87 | #endif | |
88 | ||
89 | #ifdef CONFIG_INLINE_READ_UNLOCK_BH | |
90 | #define _read_unlock_bh(lock) __read_unlock_bh(lock) | |
91 | #endif | |
92 | ||
93 | #ifdef CONFIG_INLINE_WRITE_UNLOCK_BH | |
94 | #define _write_unlock_bh(lock) __write_unlock_bh(lock) | |
95 | #endif | |
96 | ||
97 | #ifdef CONFIG_INLINE_READ_UNLOCK_IRQ | |
98 | #define _read_unlock_irq(lock) __read_unlock_irq(lock) | |
99 | #endif | |
100 | ||
101 | #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ | |
102 | #define _write_unlock_irq(lock) __write_unlock_irq(lock) | |
103 | #endif | |
104 | ||
105 | #ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE | |
106 | #define _read_unlock_irqrestore(lock, flags) __read_unlock_irqrestore(lock, flags) | |
107 | #endif | |
108 | ||
109 | #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE | |
110 | #define _write_unlock_irqrestore(lock, flags) __write_unlock_irqrestore(lock, flags) | |
111 | #endif | |
112 | ||
113 | static inline int __read_trylock(rwlock_t *lock) | |
114 | { | |
115 | preempt_disable(); | |
9828ea9d | 116 | if (do_raw_read_trylock(lock)) { |
6b6b4792 TG |
117 | rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_); |
118 | return 1; | |
119 | } | |
120 | preempt_enable(); | |
121 | return 0; | |
122 | } | |
123 | ||
124 | static inline int __write_trylock(rwlock_t *lock) | |
125 | { | |
126 | preempt_disable(); | |
9828ea9d | 127 | if (do_raw_write_trylock(lock)) { |
6b6b4792 TG |
128 | rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_); |
129 | return 1; | |
130 | } | |
131 | preempt_enable(); | |
132 | return 0; | |
133 | } | |
134 | ||
135 | /* | |
136 | * If lockdep is enabled then we use the non-preemption spin-ops | |
137 | * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are | |
138 | * not re-enabled during lock-acquire (which the preempt-spin-ops do): | |
139 | */ | |
140 | #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC) | |
141 | ||
142 | static inline void __read_lock(rwlock_t *lock) | |
143 | { | |
144 | preempt_disable(); | |
145 | rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); | |
9828ea9d | 146 | LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); |
6b6b4792 TG |
147 | } |
148 | ||
149 | static inline unsigned long __read_lock_irqsave(rwlock_t *lock) | |
150 | { | |
151 | unsigned long flags; | |
152 | ||
153 | local_irq_save(flags); | |
154 | preempt_disable(); | |
155 | rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); | |
9828ea9d TG |
156 | LOCK_CONTENDED_FLAGS(lock, do_raw_read_trylock, do_raw_read_lock, |
157 | do_raw_read_lock_flags, &flags); | |
6b6b4792 TG |
158 | return flags; |
159 | } | |
160 | ||
161 | static inline void __read_lock_irq(rwlock_t *lock) | |
162 | { | |
163 | local_irq_disable(); | |
164 | preempt_disable(); | |
165 | rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); | |
9828ea9d | 166 | LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); |
6b6b4792 TG |
167 | } |
168 | ||
169 | static inline void __read_lock_bh(rwlock_t *lock) | |
170 | { | |
171 | local_bh_disable(); | |
172 | preempt_disable(); | |
173 | rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_); | |
9828ea9d | 174 | LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock); |
6b6b4792 TG |
175 | } |
176 | ||
177 | static inline unsigned long __write_lock_irqsave(rwlock_t *lock) | |
178 | { | |
179 | unsigned long flags; | |
180 | ||
181 | local_irq_save(flags); | |
182 | preempt_disable(); | |
183 | rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); | |
9828ea9d TG |
184 | LOCK_CONTENDED_FLAGS(lock, do_raw_write_trylock, do_raw_write_lock, |
185 | do_raw_write_lock_flags, &flags); | |
6b6b4792 TG |
186 | return flags; |
187 | } | |
188 | ||
189 | static inline void __write_lock_irq(rwlock_t *lock) | |
190 | { | |
191 | local_irq_disable(); | |
192 | preempt_disable(); | |
193 | rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); | |
9828ea9d | 194 | LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); |
6b6b4792 TG |
195 | } |
196 | ||
197 | static inline void __write_lock_bh(rwlock_t *lock) | |
198 | { | |
199 | local_bh_disable(); | |
200 | preempt_disable(); | |
201 | rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); | |
9828ea9d | 202 | LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); |
6b6b4792 TG |
203 | } |
204 | ||
205 | static inline void __write_lock(rwlock_t *lock) | |
206 | { | |
207 | preempt_disable(); | |
208 | rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_); | |
9828ea9d | 209 | LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock); |
6b6b4792 TG |
210 | } |
211 | ||
212 | #endif /* CONFIG_PREEMPT */ | |
213 | ||
214 | static inline void __write_unlock(rwlock_t *lock) | |
215 | { | |
216 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | |
9828ea9d | 217 | do_raw_write_unlock(lock); |
6b6b4792 TG |
218 | preempt_enable(); |
219 | } | |
220 | ||
221 | static inline void __read_unlock(rwlock_t *lock) | |
222 | { | |
223 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | |
9828ea9d | 224 | do_raw_read_unlock(lock); |
6b6b4792 TG |
225 | preempt_enable(); |
226 | } | |
227 | ||
228 | static inline void __read_unlock_irqrestore(rwlock_t *lock, unsigned long flags) | |
229 | { | |
230 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | |
9828ea9d | 231 | do_raw_read_unlock(lock); |
6b6b4792 TG |
232 | local_irq_restore(flags); |
233 | preempt_enable(); | |
234 | } | |
235 | ||
236 | static inline void __read_unlock_irq(rwlock_t *lock) | |
237 | { | |
238 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | |
9828ea9d | 239 | do_raw_read_unlock(lock); |
6b6b4792 TG |
240 | local_irq_enable(); |
241 | preempt_enable(); | |
242 | } | |
243 | ||
244 | static inline void __read_unlock_bh(rwlock_t *lock) | |
245 | { | |
246 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | |
9828ea9d | 247 | do_raw_read_unlock(lock); |
6b6b4792 TG |
248 | preempt_enable_no_resched(); |
249 | local_bh_enable_ip((unsigned long)__builtin_return_address(0)); | |
250 | } | |
251 | ||
252 | static inline void __write_unlock_irqrestore(rwlock_t *lock, | |
253 | unsigned long flags) | |
254 | { | |
255 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | |
9828ea9d | 256 | do_raw_write_unlock(lock); |
6b6b4792 TG |
257 | local_irq_restore(flags); |
258 | preempt_enable(); | |
259 | } | |
260 | ||
261 | static inline void __write_unlock_irq(rwlock_t *lock) | |
262 | { | |
263 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | |
9828ea9d | 264 | do_raw_write_unlock(lock); |
6b6b4792 TG |
265 | local_irq_enable(); |
266 | preempt_enable(); | |
267 | } | |
268 | ||
269 | static inline void __write_unlock_bh(rwlock_t *lock) | |
270 | { | |
271 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | |
9828ea9d | 272 | do_raw_write_unlock(lock); |
6b6b4792 TG |
273 | preempt_enable_no_resched(); |
274 | local_bh_enable_ip((unsigned long)__builtin_return_address(0)); | |
275 | } | |
276 | ||
277 | #endif /* __LINUX_RWLOCK_API_SMP_H */ |