diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2009-03-31 15:03:59 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2009-03-31 15:03:59 +0100 |
commit | 5f0dffe668f2792978a8a07520d43df0dd5d7ce3 (patch) | |
tree | 020653b758bd5823cb134c651256dee7dc821990 /xen/common/spinlock.c | |
parent | c2901a5cc44c85a9ceeebd47ff21946bb35ba930 (diff) | |
download | xen-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.c | 21 |
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; } |