Line data Source code
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 _raw_read_lock(rwlock_t *lock) __acquires(lock);
19 : void __lockfunc _raw_write_lock(rwlock_t *lock) __acquires(lock);
20 : void __lockfunc _raw_read_lock_bh(rwlock_t *lock) __acquires(lock);
21 : void __lockfunc _raw_write_lock_bh(rwlock_t *lock) __acquires(lock);
22 : void __lockfunc _raw_read_lock_irq(rwlock_t *lock) __acquires(lock);
23 : void __lockfunc _raw_write_lock_irq(rwlock_t *lock) __acquires(lock);
24 : unsigned long __lockfunc _raw_read_lock_irqsave(rwlock_t *lock)
25 : __acquires(lock);
26 : unsigned long __lockfunc _raw_write_lock_irqsave(rwlock_t *lock)
27 : __acquires(lock);
28 : int __lockfunc _raw_read_trylock(rwlock_t *lock);
29 : int __lockfunc _raw_write_trylock(rwlock_t *lock);
30 : void __lockfunc _raw_read_unlock(rwlock_t *lock) __releases(lock);
31 : void __lockfunc _raw_write_unlock(rwlock_t *lock) __releases(lock);
32 : void __lockfunc _raw_read_unlock_bh(rwlock_t *lock) __releases(lock);
33 : void __lockfunc _raw_write_unlock_bh(rwlock_t *lock) __releases(lock);
34 : void __lockfunc _raw_read_unlock_irq(rwlock_t *lock) __releases(lock);
35 : void __lockfunc _raw_write_unlock_irq(rwlock_t *lock) __releases(lock);
36 : void __lockfunc
37 : _raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
38 : __releases(lock);
39 : void __lockfunc
40 : _raw_write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
41 : __releases(lock);
42 :
43 : #ifdef CONFIG_INLINE_READ_LOCK
44 : #define _raw_read_lock(lock) __raw_read_lock(lock)
45 : #endif
46 :
47 : #ifdef CONFIG_INLINE_WRITE_LOCK
48 : #define _raw_write_lock(lock) __raw_write_lock(lock)
49 : #endif
50 :
51 : #ifdef CONFIG_INLINE_READ_LOCK_BH
52 : #define _raw_read_lock_bh(lock) __raw_read_lock_bh(lock)
53 : #endif
54 :
55 : #ifdef CONFIG_INLINE_WRITE_LOCK_BH
56 : #define _raw_write_lock_bh(lock) __raw_write_lock_bh(lock)
57 : #endif
58 :
59 : #ifdef CONFIG_INLINE_READ_LOCK_IRQ
60 : #define _raw_read_lock_irq(lock) __raw_read_lock_irq(lock)
61 : #endif
62 :
63 : #ifdef CONFIG_INLINE_WRITE_LOCK_IRQ
64 : #define _raw_write_lock_irq(lock) __raw_write_lock_irq(lock)
65 : #endif
66 :
67 : #ifdef CONFIG_INLINE_READ_LOCK_IRQSAVE
68 : #define _raw_read_lock_irqsave(lock) __raw_read_lock_irqsave(lock)
69 : #endif
70 :
71 : #ifdef CONFIG_INLINE_WRITE_LOCK_IRQSAVE
72 : #define _raw_write_lock_irqsave(lock) __raw_write_lock_irqsave(lock)
73 : #endif
74 :
75 : #ifdef CONFIG_INLINE_READ_TRYLOCK
76 : #define _raw_read_trylock(lock) __raw_read_trylock(lock)
77 : #endif
78 :
79 : #ifdef CONFIG_INLINE_WRITE_TRYLOCK
80 : #define _raw_write_trylock(lock) __raw_write_trylock(lock)
81 : #endif
82 :
83 : #ifdef CONFIG_INLINE_READ_UNLOCK
84 : #define _raw_read_unlock(lock) __raw_read_unlock(lock)
85 : #endif
86 :
87 : #ifdef CONFIG_INLINE_WRITE_UNLOCK
88 : #define _raw_write_unlock(lock) __raw_write_unlock(lock)
89 : #endif
90 :
91 : #ifdef CONFIG_INLINE_READ_UNLOCK_BH
92 : #define _raw_read_unlock_bh(lock) __raw_read_unlock_bh(lock)
93 : #endif
94 :
95 : #ifdef CONFIG_INLINE_WRITE_UNLOCK_BH
96 : #define _raw_write_unlock_bh(lock) __raw_write_unlock_bh(lock)
97 : #endif
98 :
99 : #ifdef CONFIG_INLINE_READ_UNLOCK_IRQ
100 : #define _raw_read_unlock_irq(lock) __raw_read_unlock_irq(lock)
101 : #endif
102 :
103 : #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQ
104 : #define _raw_write_unlock_irq(lock) __raw_write_unlock_irq(lock)
105 : #endif
106 :
107 : #ifdef CONFIG_INLINE_READ_UNLOCK_IRQRESTORE
108 : #define _raw_read_unlock_irqrestore(lock, flags) \
109 : __raw_read_unlock_irqrestore(lock, flags)
110 : #endif
111 :
112 : #ifdef CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE
113 : #define _raw_write_unlock_irqrestore(lock, flags) \
114 : __raw_write_unlock_irqrestore(lock, flags)
115 : #endif
116 :
117 0 : static inline int __raw_read_trylock(rwlock_t *lock)
118 : {
119 0 : preempt_disable();
120 0 : if (do_raw_read_trylock(lock)) {
121 0 : rwlock_acquire_read(&lock->dep_map, 0, 1, _RET_IP_);
122 0 : return 1;
123 : }
124 0 : preempt_enable();
125 0 : return 0;
126 : }
127 :
128 0 : static inline int __raw_write_trylock(rwlock_t *lock)
129 : {
130 0 : preempt_disable();
131 0 : if (do_raw_write_trylock(lock)) {
132 0 : rwlock_acquire(&lock->dep_map, 0, 1, _RET_IP_);
133 0 : return 1;
134 : }
135 0 : preempt_enable();
136 0 : return 0;
137 : }
138 :
139 : /*
140 : * If lockdep is enabled then we use the non-preemption spin-ops
141 : * even on CONFIG_PREEMPT, because lockdep assumes that interrupts are
142 : * not re-enabled during lock-acquire (which the preempt-spin-ops do):
143 : */
144 : #if !defined(CONFIG_GENERIC_LOCKBREAK) || defined(CONFIG_DEBUG_LOCK_ALLOC)
145 :
146 36691 : static inline void __raw_read_lock(rwlock_t *lock)
147 : {
148 36691 : preempt_disable();
149 36691 : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
150 36690 : LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
151 36691 : }
152 :
153 5028 : static inline unsigned long __raw_read_lock_irqsave(rwlock_t *lock)
154 : {
155 5028 : unsigned long flags;
156 :
157 10057 : local_irq_save(flags);
158 5029 : preempt_disable();
159 5029 : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
160 5029 : LOCK_CONTENDED_FLAGS(lock, do_raw_read_trylock, do_raw_read_lock,
161 : do_raw_read_lock_flags, &flags);
162 5029 : return flags;
163 : }
164 :
165 0 : static inline void __raw_read_lock_irq(rwlock_t *lock)
166 : {
167 0 : local_irq_disable();
168 0 : preempt_disable();
169 0 : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
170 0 : LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
171 0 : }
172 :
173 41 : static inline void __raw_read_lock_bh(rwlock_t *lock)
174 : {
175 41 : __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
176 41 : rwlock_acquire_read(&lock->dep_map, 0, 0, _RET_IP_);
177 41 : LOCK_CONTENDED(lock, do_raw_read_trylock, do_raw_read_lock);
178 41 : }
179 :
180 0 : static inline unsigned long __raw_write_lock_irqsave(rwlock_t *lock)
181 : {
182 0 : unsigned long flags;
183 :
184 0 : local_irq_save(flags);
185 0 : preempt_disable();
186 0 : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
187 0 : LOCK_CONTENDED_FLAGS(lock, do_raw_write_trylock, do_raw_write_lock,
188 : do_raw_write_lock_flags, &flags);
189 0 : return flags;
190 : }
191 :
192 14258 : static inline void __raw_write_lock_irq(rwlock_t *lock)
193 : {
194 14258 : local_irq_disable();
195 14256 : preempt_disable();
196 14257 : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
197 14257 : LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
198 14261 : }
199 :
200 827 : static inline void __raw_write_lock_bh(rwlock_t *lock)
201 : {
202 827 : __local_bh_disable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
203 827 : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
204 827 : LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
205 827 : }
206 :
207 7479 : static inline void __raw_write_lock(rwlock_t *lock)
208 : {
209 7479 : preempt_disable();
210 7479 : rwlock_acquire(&lock->dep_map, 0, 0, _RET_IP_);
211 7479 : LOCK_CONTENDED(lock, do_raw_write_trylock, do_raw_write_lock);
212 7479 : }
213 :
214 : #endif /* !CONFIG_GENERIC_LOCKBREAK || CONFIG_DEBUG_LOCK_ALLOC */
215 :
216 7481 : static inline void __raw_write_unlock(rwlock_t *lock)
217 : {
218 7481 : rwlock_release(&lock->dep_map, _RET_IP_);
219 7481 : do_raw_write_unlock(lock);
220 7481 : preempt_enable();
221 7481 : }
222 :
223 36691 : static inline void __raw_read_unlock(rwlock_t *lock)
224 : {
225 36691 : rwlock_release(&lock->dep_map, _RET_IP_);
226 36689 : do_raw_read_unlock(lock);
227 36691 : preempt_enable();
228 36691 : }
229 :
230 : static inline void
231 5029 : __raw_read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
232 : {
233 5029 : rwlock_release(&lock->dep_map, _RET_IP_);
234 5028 : do_raw_read_unlock(lock);
235 5029 : local_irq_restore(flags);
236 5028 : preempt_enable();
237 5028 : }
238 :
239 0 : static inline void __raw_read_unlock_irq(rwlock_t *lock)
240 : {
241 0 : rwlock_release(&lock->dep_map, _RET_IP_);
242 0 : do_raw_read_unlock(lock);
243 0 : local_irq_enable();
244 0 : preempt_enable();
245 0 : }
246 :
247 41 : static inline void __raw_read_unlock_bh(rwlock_t *lock)
248 : {
249 41 : rwlock_release(&lock->dep_map, _RET_IP_);
250 41 : do_raw_read_unlock(lock);
251 41 : __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
252 41 : }
253 :
254 0 : static inline void __raw_write_unlock_irqrestore(rwlock_t *lock,
255 : unsigned long flags)
256 : {
257 0 : rwlock_release(&lock->dep_map, _RET_IP_);
258 0 : do_raw_write_unlock(lock);
259 0 : local_irq_restore(flags);
260 0 : preempt_enable();
261 0 : }
262 :
263 14259 : static inline void __raw_write_unlock_irq(rwlock_t *lock)
264 : {
265 14259 : rwlock_release(&lock->dep_map, _RET_IP_);
266 14258 : do_raw_write_unlock(lock);
267 14260 : local_irq_enable();
268 14260 : preempt_enable();
269 14260 : }
270 :
271 825 : static inline void __raw_write_unlock_bh(rwlock_t *lock)
272 : {
273 825 : rwlock_release(&lock->dep_map, _RET_IP_);
274 825 : do_raw_write_unlock(lock);
275 825 : __local_bh_enable_ip(_RET_IP_, SOFTIRQ_LOCK_OFFSET);
276 825 : }
277 :
278 : #endif /* __LINUX_RWLOCK_API_SMP_H */
|