summaryrefslogtreecommitdiff
path: root/kernel/spinlock.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2005-01-19 23:28:52 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-19 23:28:52 -0800
commit8522703fd856bebf42b41df1430632ffcdb8a705 (patch)
tree84efcdd3f1112e93f71b84b9d0197f8e1529c5ed /kernel/spinlock.c
parent8edee05783bfca65fb395f829fe74705047d65f9 (diff)
[PATCH] nonintrusive spin-polling loop in kernel/spinlock.c
This re-implements the nonintrusive spin-polling loop for the SMP+PREEMPT spinlock/rwlock variants, using the new *_can_lock() primitives. (The patch also adds *_can_lock() to the UP branch of spinlock.h, for completeness.) build- and boot-tested on x86 SMP+PREEMPT and SMP+!PREEMPT. Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel/spinlock.c')
-rw-r--r--kernel/spinlock.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/kernel/spinlock.c b/kernel/spinlock.c
index b485593430ec..b8e76ca8a001 100644
--- a/kernel/spinlock.c
+++ b/kernel/spinlock.c
@@ -174,7 +174,7 @@ EXPORT_SYMBOL(_write_lock);
*/
#define BUILD_LOCK_OPS(op, locktype) \
-void __lockfunc _##op##_lock(locktype *lock) \
+void __lockfunc _##op##_lock(locktype##_t *lock) \
{ \
preempt_disable(); \
for (;;) { \
@@ -183,14 +183,15 @@ void __lockfunc _##op##_lock(locktype *lock) \
preempt_enable(); \
if (!(lock)->break_lock) \
(lock)->break_lock = 1; \
- cpu_relax(); \
+ while (!op##_can_lock(lock) && (lock)->break_lock) \
+ cpu_relax(); \
preempt_disable(); \
} \
} \
\
EXPORT_SYMBOL(_##op##_lock); \
\
-unsigned long __lockfunc _##op##_lock_irqsave(locktype *lock) \
+unsigned long __lockfunc _##op##_lock_irqsave(locktype##_t *lock) \
{ \
unsigned long flags; \
\
@@ -204,7 +205,8 @@ unsigned long __lockfunc _##op##_lock_irqsave(locktype *lock) \
preempt_enable(); \
if (!(lock)->break_lock) \
(lock)->break_lock = 1; \
- cpu_relax(); \
+ while (!op##_can_lock(lock) && (lock)->break_lock) \
+ cpu_relax(); \
preempt_disable(); \
} \
return flags; \
@@ -212,14 +214,14 @@ unsigned long __lockfunc _##op##_lock_irqsave(locktype *lock) \
\
EXPORT_SYMBOL(_##op##_lock_irqsave); \
\
-void __lockfunc _##op##_lock_irq(locktype *lock) \
+void __lockfunc _##op##_lock_irq(locktype##_t *lock) \
{ \
_##op##_lock_irqsave(lock); \
} \
\
EXPORT_SYMBOL(_##op##_lock_irq); \
\
-void __lockfunc _##op##_lock_bh(locktype *lock) \
+void __lockfunc _##op##_lock_bh(locktype##_t *lock) \
{ \
unsigned long flags; \
\
@@ -244,9 +246,9 @@ EXPORT_SYMBOL(_##op##_lock_bh)
* _[spin|read|write]_lock_irqsave()
* _[spin|read|write]_lock_bh()
*/
-BUILD_LOCK_OPS(spin, spinlock_t);
-BUILD_LOCK_OPS(read, rwlock_t);
-BUILD_LOCK_OPS(write, rwlock_t);
+BUILD_LOCK_OPS(spin, spinlock);
+BUILD_LOCK_OPS(read, rwlock);
+BUILD_LOCK_OPS(write, rwlock);
#endif /* CONFIG_PREEMPT */