Import 2.3.18pre1
[davej-history.git] / include / asm-i386 / spinlock.h
blobf8254a4929f742c16ee85727adf6728331b64d2d
1 #ifndef __ASM_SPINLOCK_H
2 #define __ASM_SPINLOCK_H
4 /*
5 * Your basic SMP spinlocks, allowing only a single CPU anywhere
6 */
8 typedef struct {
9 volatile unsigned int lock;
10 } spinlock_t;
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 \
28 "\n1:\t" \
29 "lock ; btsl $0,%0\n\t" \
30 "jc 2f\n" \
31 ".section .text.lock,\"ax\"\n" \
32 "2:\t" \
33 "testb $1,%0\n\t" \
34 "jne 2b\n\t" \
35 "jmp 1b\n" \
36 ".previous"
38 #define spin_unlock_string \
39 "lock ; btrl $0,%0"
41 #define spin_lock(lock) \
42 __asm__ __volatile__( \
43 spin_lock_string \
44 :"=m" (__dummy_lock(lock)))
46 #define spin_unlock(lock) \
47 __asm__ __volatile__( \
48 spin_unlock_string \
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
61 * read-locks.
63 typedef struct {
64 volatile unsigned int lock;
65 unsigned long previous;
66 } rwlock_t;
68 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
71 * On x86, we implement read-write locks as a 32-bit counter
72 * with the high bit (sign) being the "write" bit.
74 * The inline assembly is non-obvious. Think about it.
76 #define read_lock(rw) \
77 asm volatile("\n1:\t" \
78 "lock ; incl %0\n\t" \
79 "js 2f\n" \
80 ".section .text.lock,\"ax\"\n" \
81 "2:\tlock ; decl %0\n" \
82 "3:\tcmpl $0,%0\n\t" \
83 "js 3b\n\t" \
84 "jmp 1b\n" \
85 ".previous" \
86 :"=m" (__dummy_lock(&(rw)->lock)))
88 #define read_unlock(rw) \
89 asm volatile("lock ; decl %0" \
90 :"=m" (__dummy_lock(&(rw)->lock)))
92 #define write_lock(rw) \
93 asm volatile("\n1:\t" \
94 "lock ; btsl $31,%0\n\t" \
95 "jc 4f\n" \
96 "2:\ttestl $0x7fffffff,%0\n\t" \
97 "jne 3f\n" \
98 ".section .text.lock,\"ax\"\n" \
99 "3:\tlock ; btrl $31,%0\n" \
100 "4:\tcmp $0,%0\n\t" \
101 "jne 4b\n\t" \
102 "jmp 1b\n" \
103 ".previous" \
104 :"=m" (__dummy_lock(&(rw)->lock)))
106 #define write_unlock(rw) \
107 asm volatile("lock ; btrl $31,%0":"=m" (__dummy_lock(&(rw)->lock)))
109 #endif /* __ASM_SPINLOCK_H */