aboutsummaryrefslogtreecommitdiffstats
path: root/xen/common/spinlock.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-03-31 15:03:59 +0100
committerKeir Fraser <keir.fraser@citrix.com>2009-03-31 15:03:59 +0100
commit5f0dffe668f2792978a8a07520d43df0dd5d7ce3 (patch)
tree020653b758bd5823cb134c651256dee7dc821990 /xen/common/spinlock.c
parentc2901a5cc44c85a9ceeebd47ff21946bb35ba930 (diff)
downloadxen-5f0dffe668f2792978a8a07520d43df0dd5d7ce3.tar.gz
xen-5f0dffe668f2792978a8a07520d43df0dd5d7ce3.tar.bz2
xen-5f0dffe668f2792978a8a07520d43df0dd5d7ce3.zip
Simplify spinlock code and re-enable IRQs where possible when spinning.
Based on a patch by Juergen Gross. Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Diffstat (limited to 'xen/common/spinlock.c')
-rw-r--r--xen/common/spinlock.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/xen/common/spinlock.c b/xen/common/spinlock.c
index 002f82eee4..ac2aaab814 100644
--- a/xen/common/spinlock.c
+++ b/xen/common/spinlock.c
@@ -2,6 +2,7 @@
#include <xen/irq.h>
#include <xen/smp.h>
#include <xen/spinlock.h>
+#include <asm/processor.h>
#ifndef NDEBUG
@@ -43,7 +44,9 @@ void spin_debug_disable(void)
void _spin_lock(spinlock_t *lock)
{
check_lock(&lock->debug);
- _raw_spin_lock(&lock->raw);
+ while ( unlikely(!_raw_spin_trylock(&lock->raw)) )
+ while ( likely(_raw_spin_is_locked(&lock->raw)) )
+ cpu_relax();
}
void _spin_lock_irq(spinlock_t *lock)
@@ -51,7 +54,13 @@ void _spin_lock_irq(spinlock_t *lock)
ASSERT(local_irq_is_enabled());
local_irq_disable();
check_lock(&lock->debug);
- _raw_spin_lock(&lock->raw);
+ while ( unlikely(!_raw_spin_trylock(&lock->raw)) )
+ {
+ local_irq_enable();
+ while ( likely(_raw_spin_is_locked(&lock->raw)) )
+ cpu_relax();
+ local_irq_disable();
+ }
}
unsigned long _spin_lock_irqsave(spinlock_t *lock)
@@ -59,7 +68,13 @@ unsigned long _spin_lock_irqsave(spinlock_t *lock)
unsigned long flags;
local_irq_save(flags);
check_lock(&lock->debug);
- _raw_spin_lock(&lock->raw);
+ while ( unlikely(!_raw_spin_trylock(&lock->raw)) )
+ {
+ local_irq_restore(flags);
+ while ( likely(_raw_spin_is_locked(&lock->raw)) )
+ cpu_relax();
+ local_irq_save(flags);
+ }
return flags;
}