1 #ifndef __ASM_SPINLOCK_H
2 #define __ASM_SPINLOCK_H
5 * Your basic SMP spinlocks, allowing only a single CPU anywhere
9 volatile unsigned int lock
;
12 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
14 #define spin_lock_init(x) do { (x)->lock = 0; } while(0)
16 * Simple spin lock operations. There are two variants, one clears IRQ's
17 * on the local processor, one does not.
19 * We make no fairness assumptions. They have a cost.
22 #define spin_unlock_wait(x) do { barrier(); } while(((volatile spinlock_t *)(x))->lock)
24 typedef struct { unsigned long a
[100]; } __dummy_lock_t
;
25 #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
27 #define spin_lock_string \
29 "lock ; btsl $0,%0\n\t" \
31 ".section .text.lock,\"ax\"\n" \
38 #define spin_unlock_string \
41 #define spin_lock(lock) \
42 __asm__ __volatile__( \
44 :"=m" (__dummy_lock(lock)))
46 #define spin_unlock(lock) \
47 __asm__ __volatile__( \
49 :"=m" (__dummy_lock(lock)))
51 #define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
54 * Read-write spinlocks, allowing multiple readers
55 * but only one writer.
57 * NOTE! it is quite common to have readers in interrupts
58 * but no interrupt writers. For those circumstances we
59 * can "mix" irq-safe locks - any writer needs to get a
60 * irq-safe write-lock, but readers can get non-irqsafe
64 volatile unsigned int lock
;
67 #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
70 * On x86, we implement read-write locks as a 32-bit counter
71 * with the high bit (sign) being the "write" bit.
73 * The inline assembly is non-obvious. Think about it.
75 #define read_lock(rw) \
76 asm volatile("\n1:\t" \
77 "lock ; incl %0\n\t" \
79 ".section .text.lock,\"ax\"\n" \
80 "2:\tlock ; decl %0\n" \
81 "3:\tcmpl $0,%0\n\t" \
85 :"=m" (__dummy_lock(&(rw)->lock)))
87 #define read_unlock(rw) \
88 asm volatile("lock ; decl %0" \
89 :"=m" (__dummy_lock(&(rw)->lock)))
91 #define write_lock(rw) \
92 asm volatile("\n1:\t" \
93 "lock ; btsl $31,%0\n\t" \
95 "2:\ttestl $0x7fffffff,%0\n\t" \
97 ".section .text.lock,\"ax\"\n" \
98 "3:\tlock ; btrl $31,%0\n" \
103 :"=m" (__dummy_lock(&(rw)->lock)))
105 #define write_unlock(rw) \
106 asm volatile("lock ; btrl $31,%0":"=m" (__dummy_lock(&(rw)->lock)))
108 #endif /* __ASM_SPINLOCK_H */