00001 #ifndef ARCH_SMP_SPINLOCK_H
00002 #define ARCH_SMP_SPINLOCK_H
00003
00004
00005
00006
00007
00008 typedef struct {
00009 volatile unsigned int lock;
00010 } spinlock_t;
00011
00012
00013 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
00014
00015
00016
00017
00018
00019
00020
00021 #define barrier() __asm__ __volatile__("": : :"memory")
00022 #define spin_is_locked(x) (*(volatile char *)(&(x)->lock) <= 0)
00023 #define spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
00024
00025 #define spin_lock_string \
00026 "\n1:\t" \
00027 "lock ; decb %0\n\t" \
00028 "js 2f\n" \
00029 ".section .text.lock,\"ax\"\n" \
00030 "2:\t" \
00031 "cmpb $0,%0\n\t" \
00032 "rep;nop\n\t" \
00033 "jle 2b\n\t" \
00034 "jmp 1b\n" \
00035 ".previous"
00036
00037
00038
00039
00040 #define spin_unlock_string \
00041 "movb $1,%0"
00042
00043 static inline __attribute__((always_inline)) void spin_lock(spinlock_t *lock)
00044 {
00045 __asm__ __volatile__(
00046 spin_lock_string
00047 :"=m" (lock->lock) : : "memory");
00048 }
00049
00050 static inline __attribute__((always_inline)) void spin_unlock(spinlock_t *lock)
00051 {
00052 __asm__ __volatile__(
00053 spin_unlock_string
00054 :"=m" (lock->lock) : : "memory");
00055 }
00056
00057
00058 static inline __attribute__((always_inline)) void cpu_relax(void)
00059 {
00060 __asm__ __volatile__("rep;nop": : :"memory");
00061 }
00062
00063 #endif