Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef _ALPHA_SPINLOCK_H |
2 | #define _ALPHA_SPINLOCK_H | |
3 | ||
1da177e4 LT |
4 | #include <linux/kernel.h> |
5 | #include <asm/current.h> | |
6 | ||
1da177e4 LT |
7 | /* |
8 | * Simple spin lock operations. There are two variants, one clears IRQ's | |
9 | * on the local processor, one does not. | |
10 | * | |
11 | * We make no fairness assumptions. They have a cost. | |
12 | */ | |
13 | ||
0199c4e6 TG |
14 | #define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) |
15 | #define arch_spin_is_locked(x) ((x)->lock != 0) | |
16 | #define arch_spin_unlock_wait(x) \ | |
fb1c8f93 IM |
17 | do { cpu_relax(); } while ((x)->lock) |
18 | ||
0199c4e6 | 19 | static inline void arch_spin_unlock(arch_spinlock_t * lock) |
1da177e4 LT |
20 | { |
21 | mb(); | |
22 | lock->lock = 0; | |
23 | } | |
24 | ||
0199c4e6 | 25 | static inline void arch_spin_lock(arch_spinlock_t * lock) |
1da177e4 LT |
26 | { |
27 | long tmp; | |
28 | ||
29 | __asm__ __volatile__( | |
30 | "1: ldl_l %0,%1\n" | |
31 | " bne %0,2f\n" | |
32 | " lda %0,1\n" | |
33 | " stl_c %0,%1\n" | |
34 | " beq %0,2f\n" | |
35 | " mb\n" | |
36 | ".subsection 2\n" | |
37 | "2: ldl %0,%1\n" | |
38 | " bne %0,2b\n" | |
39 | " br 1b\n" | |
40 | ".previous" | |
41 | : "=&r" (tmp), "=m" (lock->lock) | |
42 | : "m"(lock->lock) : "memory"); | |
43 | } | |
44 | ||
0199c4e6 | 45 | static inline int arch_spin_trylock(arch_spinlock_t *lock) |
1da177e4 LT |
46 | { |
47 | return !test_and_set_bit(0, &lock->lock); | |
48 | } | |
1da177e4 LT |
49 | |
50 | /***********************************************************/ | |
51 | ||
e5931943 | 52 | static inline int arch_read_can_lock(arch_rwlock_t *lock) |
1da177e4 LT |
53 | { |
54 | return (lock->lock & 1) == 0; | |
55 | } | |
56 | ||
e5931943 | 57 | static inline int arch_write_can_lock(arch_rwlock_t *lock) |
1da177e4 LT |
58 | { |
59 | return lock->lock == 0; | |
60 | } | |
61 | ||
e5931943 | 62 | static inline void arch_read_lock(arch_rwlock_t *lock) |
1da177e4 LT |
63 | { |
64 | long regx; | |
65 | ||
66 | __asm__ __volatile__( | |
67 | "1: ldl_l %1,%0\n" | |
fb1c8f93 IM |
68 | " blbs %1,6f\n" |
69 | " subl %1,2,%1\n" | |
1da177e4 LT |
70 | " stl_c %1,%0\n" |
71 | " beq %1,6f\n" | |
72 | " mb\n" | |
73 | ".subsection 2\n" | |
74 | "6: ldl %1,%0\n" | |
fb1c8f93 | 75 | " blbs %1,6b\n" |
1da177e4 LT |
76 | " br 1b\n" |
77 | ".previous" | |
78 | : "=m" (*lock), "=&r" (regx) | |
79 | : "m" (*lock) : "memory"); | |
80 | } | |
81 | ||
e5931943 | 82 | static inline void arch_write_lock(arch_rwlock_t *lock) |
1da177e4 LT |
83 | { |
84 | long regx; | |
85 | ||
86 | __asm__ __volatile__( | |
87 | "1: ldl_l %1,%0\n" | |
fb1c8f93 IM |
88 | " bne %1,6f\n" |
89 | " lda %1,1\n" | |
1da177e4 LT |
90 | " stl_c %1,%0\n" |
91 | " beq %1,6f\n" | |
92 | " mb\n" | |
93 | ".subsection 2\n" | |
94 | "6: ldl %1,%0\n" | |
fb1c8f93 | 95 | " bne %1,6b\n" |
1da177e4 LT |
96 | " br 1b\n" |
97 | ".previous" | |
98 | : "=m" (*lock), "=&r" (regx) | |
99 | : "m" (*lock) : "memory"); | |
100 | } | |
1da177e4 | 101 | |
e5931943 | 102 | static inline int arch_read_trylock(arch_rwlock_t * lock) |
1da177e4 LT |
103 | { |
104 | long regx; | |
105 | int success; | |
106 | ||
107 | __asm__ __volatile__( | |
108 | "1: ldl_l %1,%0\n" | |
109 | " lda %2,0\n" | |
110 | " blbs %1,2f\n" | |
111 | " subl %1,2,%2\n" | |
112 | " stl_c %2,%0\n" | |
113 | " beq %2,6f\n" | |
114 | "2: mb\n" | |
115 | ".subsection 2\n" | |
116 | "6: br 1b\n" | |
117 | ".previous" | |
118 | : "=m" (*lock), "=&r" (regx), "=&r" (success) | |
119 | : "m" (*lock) : "memory"); | |
120 | ||
121 | return success; | |
122 | } | |
123 | ||
e5931943 | 124 | static inline int arch_write_trylock(arch_rwlock_t * lock) |
1da177e4 LT |
125 | { |
126 | long regx; | |
127 | int success; | |
128 | ||
129 | __asm__ __volatile__( | |
130 | "1: ldl_l %1,%0\n" | |
131 | " lda %2,0\n" | |
132 | " bne %1,2f\n" | |
133 | " lda %2,1\n" | |
134 | " stl_c %2,%0\n" | |
135 | " beq %2,6f\n" | |
136 | "2: mb\n" | |
137 | ".subsection 2\n" | |
138 | "6: br 1b\n" | |
139 | ".previous" | |
140 | : "=m" (*lock), "=&r" (regx), "=&r" (success) | |
141 | : "m" (*lock) : "memory"); | |
142 | ||
143 | return success; | |
144 | } | |
145 | ||
e5931943 | 146 | static inline void arch_read_unlock(arch_rwlock_t * lock) |
1da177e4 LT |
147 | { |
148 | long regx; | |
149 | __asm__ __volatile__( | |
150 | " mb\n" | |
151 | "1: ldl_l %1,%0\n" | |
152 | " addl %1,2,%1\n" | |
153 | " stl_c %1,%0\n" | |
154 | " beq %1,6f\n" | |
155 | ".subsection 2\n" | |
156 | "6: br 1b\n" | |
157 | ".previous" | |
158 | : "=m" (*lock), "=&r" (regx) | |
159 | : "m" (*lock) : "memory"); | |
160 | } | |
161 | ||
e5931943 | 162 | static inline void arch_write_unlock(arch_rwlock_t * lock) |
fb1c8f93 IM |
163 | { |
164 | mb(); | |
165 | lock->lock = 0; | |
166 | } | |
167 | ||
e5931943 TG |
168 | #define arch_read_lock_flags(lock, flags) arch_read_lock(lock) |
169 | #define arch_write_lock_flags(lock, flags) arch_write_lock(lock) | |
f5f7eac4 | 170 | |
1da177e4 | 171 | #endif /* _ALPHA_SPINLOCK_H */ |