diff options
author | Hollis Blanchard <hollisb@us.ibm.com> | 2006-11-29 14:16:36 -0600 |
---|---|---|
committer | Hollis Blanchard <hollisb@us.ibm.com> | 2006-11-29 14:16:36 -0600 |
commit | ab26a6a563a0acb589af87a8e063c0e171d75665 (patch) | |
tree | 71a432bde5d016e928ab3ad7860fca01312ec787 /extras/mini-os/include/x86/arch_spinlock.h | |
parent | d3be8a6ca1aa9312cc01e780a2fea56ab8ec12b4 (diff) | |
parent | 1c804664cf63f0c2e80d0420e52d5f82c3956685 (diff) | |
download | xen-ab26a6a563a0acb589af87a8e063c0e171d75665.tar.gz xen-ab26a6a563a0acb589af87a8e063c0e171d75665.tar.bz2 xen-ab26a6a563a0acb589af87a8e063c0e171d75665.zip |
Merge with xen-unstable.hg.
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
Diffstat (limited to 'extras/mini-os/include/x86/arch_spinlock.h')
-rw-r--r-- | extras/mini-os/include/x86/arch_spinlock.h | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/extras/mini-os/include/x86/arch_spinlock.h b/extras/mini-os/include/x86/arch_spinlock.h new file mode 100644 index 0000000000..a181ed3c92 --- /dev/null +++ b/extras/mini-os/include/x86/arch_spinlock.h @@ -0,0 +1,93 @@ + + +#ifndef __ARCH_ASM_SPINLOCK_H +#define __ARCH_ASM_SPINLOCK_H + +#include <lib.h> + + +#define ARCH_SPIN_LOCK_UNLOCKED (spinlock_t) { 1 } + +/* + * Simple spin lock operations. There are two variants, one clears IRQ's + * on the local processor, one does not. + * + * We make no fairness assumptions. They have a cost. + */ + +#define arch_spin_is_locked(x) (*(volatile signed char *)(&(x)->slock) <= 0) +#define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x)) + +#define spin_lock_string \ + "1:\n" \ + LOCK \ + "decb %0\n\t" \ + "jns 3f\n" \ + "2:\t" \ + "rep;nop\n\t" \ + "cmpb $0,%0\n\t" \ + "jle 2b\n\t" \ + "jmp 1b\n" \ + "3:\n\t" + +#define spin_lock_string_flags \ + "1:\n" \ + LOCK \ + "decb %0\n\t" \ + "jns 4f\n\t" \ + "2:\t" \ + "testl $0x200, %1\n\t" \ + "jz 3f\n\t" \ + "#sti\n\t" \ + "3:\t" \ + "rep;nop\n\t" \ + "cmpb $0, %0\n\t" \ + "jle 3b\n\t" \ + "#cli\n\t" \ + "jmp 1b\n" \ + "4:\n\t" + +/* + * This works. Despite all the confusion. + * (except on PPro SMP or if we are using OOSTORE) + * (PPro errata 66, 92) + */ + +#define spin_unlock_string \ + "xchgb %b0, %1" \ + :"=q" (oldval), "=m" (lock->slock) \ + :"0" (oldval) : "memory" + +static inline void _raw_spin_unlock(spinlock_t *lock) +{ + char oldval = 1; + __asm__ __volatile__( + spin_unlock_string + ); +} + +static inline int _raw_spin_trylock(spinlock_t *lock) +{ + char oldval; + __asm__ __volatile__( + "xchgb %b0,%1\n" + :"=q" (oldval), "=m" (lock->slock) + :"0" (0) : "memory"); + return oldval > 0; +} + +static inline void _raw_spin_lock(spinlock_t *lock) +{ + __asm__ __volatile__( + spin_lock_string + :"=m" (lock->slock) : : "memory"); +} + +static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags) +{ + __asm__ __volatile__( + spin_lock_string_flags + :"=m" (lock->slock) : "r" (flags) : "memory"); +} + +#endif |