Import 2.3.18pre1
[davej-history.git] / include / asm-alpha / spinlock.h
blob6153b2a86d9a360a8e9acbacf505f18733b13177
1 #ifndef _ALPHA_SPINLOCK_H
2 #define _ALPHA_SPINLOCK_H
4 #include <asm/system.h>
5 #include <linux/kernel.h>
6 #include <asm/current.h>
8 #define DEBUG_SPINLOCK 1
9 #define DEBUG_RWLOCK 1
12 * Simple spin lock operations. There are two variants, one clears IRQ's
13 * on the local processor, one does not.
15 * We make no fairness assumptions. They have a cost.
18 typedef struct {
19 volatile unsigned int lock /*__attribute__((aligned(32))) */;
20 #if DEBUG_SPINLOCK
21 int on_cpu;
22 int line_no;
23 void *previous;
24 struct task_struct * task;
25 const char *base_file;
26 #endif
27 } spinlock_t;
29 #if DEBUG_SPINLOCK
30 #define SPIN_LOCK_UNLOCKED (spinlock_t) {0, -1, 0, 0, 0, 0}
31 #define spin_lock_init(x) \
32 ((x)->lock = 0, (x)->on_cpu = -1, (x)->previous = 0, (x)->task = 0)
33 #else
34 #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
35 #define spin_lock_init(x) ((x)->lock = 0)
36 #endif
38 #define spin_is_locked(x) ((x)->lock != 0)
39 #define spin_unlock_wait(x) ({ do { barrier(); } while ((x)->lock); })
41 typedef struct { unsigned long a[100]; } __dummy_lock_t;
42 #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
44 #if DEBUG_SPINLOCK
45 extern void spin_unlock(spinlock_t * lock);
46 extern void debug_spin_lock(spinlock_t * lock, const char *, int);
47 extern int debug_spin_trylock(spinlock_t * lock, const char *, int);
49 #define spin_lock(LOCK) debug_spin_lock(LOCK, __BASE_FILE__, __LINE__)
50 #define spin_trylock(LOCK) debug_spin_trylock(LOCK, __BASE_FILE__, __LINE__)
52 #define spin_lock_own(LOCK, LOCATION) \
53 do { \
54 if (!((LOCK)->lock && (LOCK)->on_cpu == smp_processor_id())) \
55 printk("%s: called on %d from %p but lock %s on %d\n", \
56 LOCATION, smp_processor_id(), \
57 __builtin_return_address(0), \
58 (LOCK)->lock ? "taken" : "freed", (LOCK)->on_cpu); \
59 } while (0)
60 #else
61 static inline void spin_unlock(spinlock_t * lock)
63 mb();
64 lock->lock = 0;
67 static inline void spin_lock(spinlock_t * lock)
69 long tmp;
71 /* Use sub-sections to put the actual loop at the end
72 of this object file's text section so as to perfect
73 branch prediction. */
74 __asm__ __volatile__(
75 "1: ldl_l %0,%1\n"
76 " blbs %0,2f\n"
77 " or %0,1,%0\n"
78 " stl_c %0,%1\n"
79 " beq %0,2f\n"
80 " mb\n"
81 ".section .text2,\"ax\"\n"
82 "2: ldl %0,%1\n"
83 " blbs %0,2b\n"
84 " br 1b\n"
85 ".previous"
86 : "=r" (tmp), "=m" (__dummy_lock(lock))
87 : "m"(__dummy_lock(lock)));
90 #define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
91 #define spin_lock_own(LOCK, LOCATION) ((void)0)
92 #endif /* DEBUG_SPINLOCK */
94 /***********************************************************/
96 typedef struct {
97 volatile int write_lock:1, read_counter:31;
98 } /*__attribute__((aligned(32)))*/ rwlock_t;
100 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 }
102 #if DEBUG_RWLOCK
103 extern void write_lock(rwlock_t * lock);
104 extern void read_lock(rwlock_t * lock);
105 #else
106 static inline void write_lock(rwlock_t * lock)
108 long regx;
110 __asm__ __volatile__(
111 "1: ldl_l %1,%0\n"
112 " bne %1,6f\n"
113 " or $31,1,%1\n"
114 " stl_c %1,%0\n"
115 " beq %1,6f\n"
116 " mb\n"
117 ".section .text2,\"ax\"\n"
118 "6: ldl %1,%0\n"
119 " bne %1,6b\n"
120 " br 1b\n"
121 ".previous"
122 : "=m" (__dummy_lock(lock)), "=&r" (regx)
123 : "0" (__dummy_lock(lock))
127 static inline void read_lock(rwlock_t * lock)
129 long regx;
131 __asm__ __volatile__(
132 "1: ldl_l %1,%0\n"
133 " blbs %1,6f\n"
134 " subl %1,2,%1\n"
135 " stl_c %1,%0\n"
136 " beq %1,6f\n"
137 "4: mb\n"
138 ".section .text2,\"ax\"\n"
139 "6: ldl %1,%0\n"
140 " blbs %1,6b\n"
141 " br 1b\n"
142 ".previous"
143 : "=m" (__dummy_lock(lock)), "=&r" (regx)
144 : "m" (__dummy_lock(lock))
147 #endif /* DEBUG_RWLOCK */
149 static inline void write_unlock(rwlock_t * lock)
151 mb();
152 *(volatile int *)lock = 0;
155 static inline void read_unlock(rwlock_t * lock)
157 long regx;
158 __asm__ __volatile__(
159 "1: ldl_l %1,%0\n"
160 " addl %1,2,%1\n"
161 " stl_c %1,%0\n"
162 " beq %1,6f\n"
163 ".section .text2,\"ax\"\n"
164 "6: br 1b\n"
165 ".previous"
166 : "=m" (__dummy_lock(lock)), "=&r" (regx)
167 : "m" (__dummy_lock(lock)));
170 #endif /* _ALPHA_SPINLOCK_H */