2 * Copyright (2004) Linus Torvalds
4 * Author: Zwane Mwaikambo <zwane@fsmlabs.com>
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)
17 if (_raw_spin_trylock(lock))
23 EXPORT_SYMBOL(_spin_trylock);
25 int __lockfunc _write_trylock(rwlock_t *lock)
28 if (_raw_write_trylock(lock))
34 EXPORT_SYMBOL(_write_trylock);
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) {
56 while (spin_is_locked(lock))
59 } while (!_raw_spin_trylock(lock));
62 void __lockfunc _spin_lock(spinlock_t *lock)
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);
78 while (rwlock_is_locked(lock))
81 } while (!_raw_write_trylock(lock));
84 void __lockfunc _write_lock(rwlock_t *lock)
87 if (unlikely(!_raw_write_trylock(lock)))
88 __preempt_write_lock(lock);
91 void __lockfunc _spin_lock(spinlock_t *lock)
97 void __lockfunc _write_lock(rwlock_t *lock)
100 _raw_write_lock(lock);
103 EXPORT_SYMBOL(_spin_lock);
104 EXPORT_SYMBOL(_write_lock);
106 void __lockfunc _read_lock(rwlock_t *lock)
109 _raw_read_lock(lock);
111 EXPORT_SYMBOL(_read_lock);
113 void __lockfunc _spin_unlock(spinlock_t *lock)
115 _raw_spin_unlock(lock);
118 EXPORT_SYMBOL(_spin_unlock);
120 void __lockfunc _write_unlock(rwlock_t *lock)
122 _raw_write_unlock(lock);
125 EXPORT_SYMBOL(_write_unlock);
127 void __lockfunc _read_unlock(rwlock_t *lock)
129 _raw_read_unlock(lock);
132 EXPORT_SYMBOL(_read_unlock);
134 unsigned long __lockfunc _spin_lock_irqsave(spinlock_t *lock)
138 local_irq_save(flags);
140 _raw_spin_lock_flags(lock, flags);
143 EXPORT_SYMBOL(_spin_lock_irqsave);
145 void __lockfunc _spin_lock_irq(spinlock_t *lock)
149 _raw_spin_lock(lock);
151 EXPORT_SYMBOL(_spin_lock_irq);
153 void __lockfunc _spin_lock_bh(spinlock_t *lock)
157 _raw_spin_lock(lock);
159 EXPORT_SYMBOL(_spin_lock_bh);
161 unsigned long __lockfunc _read_lock_irqsave(rwlock_t *lock)
165 local_irq_save(flags);
167 _raw_read_lock(lock);
170 EXPORT_SYMBOL(_read_lock_irqsave);
172 void __lockfunc _read_lock_irq(rwlock_t *lock)
176 _raw_read_lock(lock);
178 EXPORT_SYMBOL(_read_lock_irq);
180 void __lockfunc _read_lock_bh(rwlock_t *lock)
184 _raw_read_lock(lock);
186 EXPORT_SYMBOL(_read_lock_bh);
188 unsigned long __lockfunc _write_lock_irqsave(rwlock_t *lock)
192 local_irq_save(flags);
194 _raw_write_lock(lock);
197 EXPORT_SYMBOL(_write_lock_irqsave);
199 void __lockfunc _write_lock_irq(rwlock_t *lock)
203 _raw_write_lock(lock);
205 EXPORT_SYMBOL(_write_lock_irq);
207 void __lockfunc _write_lock_bh(rwlock_t *lock)
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);
221 EXPORT_SYMBOL(_spin_unlock_irqrestore);
223 void __lockfunc _spin_unlock_irq(spinlock_t *lock)
225 _raw_spin_unlock(lock);
229 EXPORT_SYMBOL(_spin_unlock_irq);
231 void __lockfunc _spin_unlock_bh(spinlock_t *lock)
233 _raw_spin_unlock(lock);
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);
245 EXPORT_SYMBOL(_read_unlock_irqrestore);
247 void __lockfunc _read_unlock_irq(rwlock_t *lock)
249 _raw_read_unlock(lock);
253 EXPORT_SYMBOL(_read_unlock_irq);
255 void __lockfunc _read_unlock_bh(rwlock_t *lock)
257 _raw_read_unlock(lock);
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);
269 EXPORT_SYMBOL(_write_unlock_irqrestore);
271 void __lockfunc _write_unlock_irq(rwlock_t *lock)
273 _raw_write_unlock(lock);
277 EXPORT_SYMBOL(_write_unlock_irq);
279 void __lockfunc _write_unlock_bh(rwlock_t *lock)
281 _raw_write_unlock(lock);
285 EXPORT_SYMBOL(_write_unlock_bh);
287 int __lockfunc _spin_trylock_bh(spinlock_t *lock)
291 if (_raw_spin_trylock(lock))
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);