spinlock.h

Go to the documentation of this file.
00001 #ifndef ARCH_SMP_SPINLOCK_H
00002 #define ARCH_SMP_SPINLOCK_H
00003 
00004 /*
00005  * Your basic SMP spinlocks, allowing only a single CPU anywhere
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  * Simple spin lock operations.  There are two variants, one clears IRQ's
00017  * on the local processor, one does not.
00018  *
00019  * We make no fairness assumptions. They have a cost.
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  * This works. Despite all the confusion.
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 /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
00058 static inline __attribute__((always_inline)) void cpu_relax(void)
00059 {
00060         __asm__ __volatile__("rep;nop": : :"memory");
00061 }
00062 
00063 #endif /* ARCH_SMP_SPINLOCK_H */

Generated on Mon Dec 29 10:54:06 2008 for coreboot by  doxygen 1.5.5