]>
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(); | |
116 | if (_raw_read_trylock(lock)) { | |
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(); | |
127 | if (_raw_write_trylock(lock)) { | |
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_); | |
146 | LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); | |
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_); | |
156 | LOCK_CONTENDED_FLAGS(lock, _raw_read_trylock, _raw_read_lock, | |
157 | _raw_read_lock_flags, &flags); | |
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_); | |
166 | LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); | |
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_); | |
174 | LOCK_CONTENDED(lock, _raw_read_trylock, _raw_read_lock); | |
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_); | |
184 | LOCK_CONTENDED_FLAGS(lock, _raw_write_trylock, _raw_write_lock, | |
185 | _raw_write_lock_flags, &flags); | |
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_); | |
194 | LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); | |
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_); | |
202 | LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); | |
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_); | |
209 | LOCK_CONTENDED(lock, _raw_write_trylock, _raw_write_lock); | |
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_); | |
217 | _raw_write_unlock(lock); | |
218 | preempt_enable(); | |
219 | } | |
220 | ||
221 | static inline void __read_unlock(rwlock_t *lock) | |
222 | { | |
223 | rwlock_release(&lock->dep_map, 1, _RET_IP_); | |
224 | _raw_read_unlock(lock); | |
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_); | |
231 | _raw_read_unlock(lock); | |
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_); | |
239 | _raw_read_unlock(lock); | |
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_); | |
247 | _raw_read_unlock(lock); | |
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_); | |
256 | _raw_write_unlock(lock); | |
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_); | |
264 | _raw_write_unlock(lock); | |
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_); | |
272 | _raw_write_unlock(lock); | |
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 */ |