[PATCH] DVB: frontend updates
[linux-2.6/history.git] / kernel / spinlock.c
blob476da1fd86f4cb0136de2a51d7dbc431cbc63442
1 /*
2 * Copyright (2004) Linus Torvalds
4 * Author: Zwane Mwaikambo <zwane@fsmlabs.com>
5 */
7 #include <linux/config.h>
8 #include <linux/linkage.h>
9 #include <linux/preempt.h>
10 #include <linux/spinlock.h>
11 #include <linux/interrupt.h>
12 #include <linux/module.h>
14 int __lockfunc _spin_trylock(spinlock_t *lock)
16 preempt_disable();
17 if (_raw_spin_trylock(lock))
18 return 1;
20 preempt_enable();
21 return 0;
23 EXPORT_SYMBOL(_spin_trylock);
25 int __lockfunc _write_trylock(rwlock_t *lock)
27 preempt_disable();
28 if (_raw_write_trylock(lock))
29 return 1;
31 preempt_enable();
32 return 0;
34 EXPORT_SYMBOL(_write_trylock);
36 #ifdef CONFIG_PREEMPT
38 * This could be a long-held lock. If another CPU holds it for a long time,
39 * and that CPU is not asked to reschedule then *this* CPU will spin on the
40 * lock for a long time, even if *this* CPU is asked to reschedule.
42 * So what we do here, in the slow (contended) path is to spin on the lock by
43 * hand while permitting preemption.
45 * Called inside preempt_disable().
47 static inline void __preempt_spin_lock(spinlock_t *lock)
49 if (preempt_count() > 1) {
50 _raw_spin_lock(lock);
51 return;
54 do {
55 preempt_enable();
56 while (spin_is_locked(lock))
57 cpu_relax();
58 preempt_disable();
59 } while (!_raw_spin_trylock(lock));
62 void __lockfunc _spin_lock(spinlock_t *lock)
64 preempt_disable();
65 if (unlikely(!_raw_spin_trylock(lock)))
66 __preempt_spin_lock(lock);
69 static inline void __preempt_write_lock(rwlock_t *lock)
71 if (preempt_count() > 1) {
72 _raw_write_lock(lock);
73 return;
76 do {
77 preempt_enable();
78 while (rwlock_is_locked(lock))
79 cpu_relax();
80 preempt_disable();
81 } while (!_raw_write_trylock(lock));
84 void __lockfunc _write_lock(rwlock_t *lock)
86 preempt_disable();
87 if (unlikely(!_raw_write_trylock(lock)))
88 __preempt_write_lock(lock);
90 #else
91 void __lockfunc _spin_lock(spinlock_t *lock)
93 preempt_disable();
94 _raw_spin_lock(lock);
97 void __lockfunc _write_lock(rwlock_t *lock)
99 preempt_disable();
100 _raw_write_lock(lock);
102 #endif
103 EXPORT_SYMBOL(_spin_lock);
104 EXPORT_SYMBOL(_write_lock);
106 void __lockfunc _read_lock(rwlock_t *lock)
108 preempt_disable();
109 _raw_read_lock(lock);
111 EXPORT_SYMBOL(_read_lock);
113 void __lockfunc _spin_unlock(spinlock_t *lock)
115 _raw_spin_unlock(lock);
116 preempt_enable();
118 EXPORT_SYMBOL(_spin_unlock);
120 void __lockfunc _write_unlock(rwlock_t *lock)
122 _raw_write_unlock(lock);
123 preempt_enable();
125 EXPORT_SYMBOL(_write_unlock);
127 void __lockfunc _read_unlock(rwlock_t *lock)
129 _raw_read_unlock(lock);
130 preempt_enable();
132 EXPORT_SYMBOL(_read_unlock);
134 unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
136 unsigned long flags;
138 local_irq_save(flags);
139 preempt_disable();
140 _raw_spin_lock_flags(lock, flags);
141 return flags;
143 EXPORT_SYMBOL(_spin_lock_irqsave);
145 void __lockfunc _spin_lock_irq(spinlock_t *lock)
147 local_irq_disable();
148 preempt_disable();
149 _raw_spin_lock(lock);
151 EXPORT_SYMBOL(_spin_lock_irq);
153 void __lockfunc _spin_lock_bh(spinlock_t *lock)
155 local_bh_disable();
156 preempt_disable();
157 _raw_spin_lock(lock);
159 EXPORT_SYMBOL(_spin_lock_bh);
161 unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
163 unsigned long flags;
165 local_irq_save(flags);
166 preempt_disable();
167 _raw_read_lock(lock);
168 return flags;
170 EXPORT_SYMBOL(_read_lock_irqsave);
172 void __lockfunc _read_lock_irq(rwlock_t *lock)
174 local_irq_disable();
175 preempt_disable();
176 _raw_read_lock(lock);
178 EXPORT_SYMBOL(_read_lock_irq);
180 void __lockfunc _read_lock_bh(rwlock_t *lock)
182 local_bh_disable();
183 preempt_disable();
184 _raw_read_lock(lock);
186 EXPORT_SYMBOL(_read_lock_bh);
188 unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
190 unsigned long flags;
192 local_irq_save(flags);
193 preempt_disable();
194 _raw_write_lock(lock);
195 return flags;
197 EXPORT_SYMBOL(_write_lock_irqsave);
199 void __lockfunc _write_lock_irq(rwlock_t *lock)
201 local_irq_disable();
202 preempt_disable();
203 _raw_write_lock(lock);
205 EXPORT_SYMBOL(_write_lock_irq);
207 void __lockfunc _write_lock_bh(rwlock_t *lock)
209 local_bh_disable();
210 preempt_disable();
211 _raw_write_lock(lock);
213 EXPORT_SYMBOL(_write_lock_bh);
215 void __lockfunc _spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
217 _raw_spin_unlock(lock);
218 local_irq_restore(flags);
219 preempt_enable();
221 EXPORT_SYMBOL(_spin_unlock_irqrestore);
223 void __lockfunc _spin_unlock_irq(spinlock_t *lock)
225 _raw_spin_unlock(lock);
226 local_irq_enable();
227 preempt_enable();
229 EXPORT_SYMBOL(_spin_unlock_irq);
231 void __lockfunc _spin_unlock_bh(spinlock_t *lock)
233 _raw_spin_unlock(lock);
234 preempt_enable();
235 local_bh_enable();
237 EXPORT_SYMBOL(_spin_unlock_bh);
239 void __lockfunc _read_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
241 _raw_read_unlock(lock);
242 local_irq_restore(flags);
243 preempt_enable();
245 EXPORT_SYMBOL(_read_unlock_irqrestore);
247 void __lockfunc _read_unlock_irq(rwlock_t *lock)
249 _raw_read_unlock(lock);
250 local_irq_enable();
251 preempt_enable();
253 EXPORT_SYMBOL(_read_unlock_irq);
255 void __lockfunc _read_unlock_bh(rwlock_t *lock)
257 _raw_read_unlock(lock);
258 preempt_enable();
259 local_bh_enable();
261 EXPORT_SYMBOL(_read_unlock_bh);
263 void __lockfunc _write_unlock_irqrestore(rwlock_t *lock, unsigned long flags)
265 _raw_write_unlock(lock);
266 local_irq_restore(flags);
267 preempt_enable();
269 EXPORT_SYMBOL(_write_unlock_irqrestore);
271 void __lockfunc _write_unlock_irq(rwlock_t *lock)
273 _raw_write_unlock(lock);
274 local_irq_enable();
275 preempt_enable();
277 EXPORT_SYMBOL(_write_unlock_irq);
279 void __lockfunc _write_unlock_bh(rwlock_t *lock)
281 _raw_write_unlock(lock);
282 preempt_enable();
283 local_bh_enable();
285 EXPORT_SYMBOL(_write_unlock_bh);
287 int __lockfunc _spin_trylock_bh(spinlock_t *lock)
289 local_bh_disable();
290 preempt_disable();
291 if (_raw_spin_trylock(lock))
292 return 1;
294 preempt_enable();
295 local_bh_enable();
296 return 0;
298 EXPORT_SYMBOL(_spin_trylock_bh);
300 int in_lock_functions(unsigned long addr)
302 /* Linker adds these: start and end of __lockfunc functions */
303 extern char __lock_text_start[], __lock_text_end[];
305 return addr >= (unsigned long)__lock_text_start
306 && addr < (unsigned long)__lock_text_end;
308 EXPORT_SYMBOL(in_lock_functions);