aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-alpha/atomic.h
diff options
context:
space:
mode:
authorIvan Kokshaysky <ink@jurassic.park.msu.ru>2005-10-21 14:06:15 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-22 22:38:33 -0400
commitd475f3f47a0427dfee483cecf9a7e9109e991423 (patch)
treebbaa882b849acf13e624e3e1d8f4d31280a4b74b /include/asm-alpha/atomic.h
parent4595f251058609d97a5d792de08c34a7956af816 (diff)
[PATCH] alpha: additional smp barriers
As stated in Documentation/atomic_ops.txt, atomic functions returning values must have the memory barriers both before and after the operation. Thanks to DaveM for pointing that out. Signed-off-by: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/asm-alpha/atomic.h')
-rw-r--r--include/asm-alpha/atomic.h12
1 files changed, 8 insertions, 4 deletions
diff --git a/include/asm-alpha/atomic.h b/include/asm-alpha/atomic.h
index 1b383e3cb68c..0b40bad00289 100644
--- a/include/asm-alpha/atomic.h
+++ b/include/asm-alpha/atomic.h
@@ -100,18 +100,19 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
100static __inline__ long atomic_add_return(int i, atomic_t * v) 100static __inline__ long atomic_add_return(int i, atomic_t * v)
101{ 101{
102 long temp, result; 102 long temp, result;
103 smp_mb();
103 __asm__ __volatile__( 104 __asm__ __volatile__(
104 "1: ldl_l %0,%1\n" 105 "1: ldl_l %0,%1\n"
105 " addl %0,%3,%2\n" 106 " addl %0,%3,%2\n"
106 " addl %0,%3,%0\n" 107 " addl %0,%3,%0\n"
107 " stl_c %0,%1\n" 108 " stl_c %0,%1\n"
108 " beq %0,2f\n" 109 " beq %0,2f\n"
109 " mb\n"
110 ".subsection 2\n" 110 ".subsection 2\n"
111 "2: br 1b\n" 111 "2: br 1b\n"
112 ".previous" 112 ".previous"
113 :"=&r" (temp), "=m" (v->counter), "=&r" (result) 113 :"=&r" (temp), "=m" (v->counter), "=&r" (result)
114 :"Ir" (i), "m" (v->counter) : "memory"); 114 :"Ir" (i), "m" (v->counter) : "memory");
115 smp_mb();
115 return result; 116 return result;
116} 117}
117 118
@@ -120,54 +121,57 @@ static __inline__ long atomic_add_return(int i, atomic_t * v)
120static __inline__ long atomic64_add_return(long i, atomic64_t * v) 121static __inline__ long atomic64_add_return(long i, atomic64_t * v)
121{ 122{
122 long temp, result; 123 long temp, result;
124 smp_mb();
123 __asm__ __volatile__( 125 __asm__ __volatile__(
124 "1: ldq_l %0,%1\n" 126 "1: ldq_l %0,%1\n"
125 " addq %0,%3,%2\n" 127 " addq %0,%3,%2\n"
126 " addq %0,%3,%0\n" 128 " addq %0,%3,%0\n"
127 " stq_c %0,%1\n" 129 " stq_c %0,%1\n"
128 " beq %0,2f\n" 130 " beq %0,2f\n"
129 " mb\n"
130 ".subsection 2\n" 131 ".subsection 2\n"
131 "2: br 1b\n" 132 "2: br 1b\n"
132 ".previous" 133 ".previous"
133 :"=&r" (temp), "=m" (v->counter), "=&r" (result) 134 :"=&r" (temp), "=m" (v->counter), "=&r" (result)
134 :"Ir" (i), "m" (v->counter) : "memory"); 135 :"Ir" (i), "m" (v->counter) : "memory");
136 smp_mb();
135 return result; 137 return result;
136} 138}
137 139
138static __inline__ long atomic_sub_return(int i, atomic_t * v) 140static __inline__ long atomic_sub_return(int i, atomic_t * v)
139{ 141{
140 long temp, result; 142 long temp, result;
143 smp_mb();
141 __asm__ __volatile__( 144 __asm__ __volatile__(
142 "1: ldl_l %0,%1\n" 145 "1: ldl_l %0,%1\n"
143 " subl %0,%3,%2\n" 146 " subl %0,%3,%2\n"
144 " subl %0,%3,%0\n" 147 " subl %0,%3,%0\n"
145 " stl_c %0,%1\n" 148 " stl_c %0,%1\n"
146 " beq %0,2f\n" 149 " beq %0,2f\n"
147 " mb\n"
148 ".subsection 2\n" 150 ".subsection 2\n"
149 "2: br 1b\n" 151 "2: br 1b\n"
150 ".previous" 152 ".previous"
151 :"=&r" (temp), "=m" (v->counter), "=&r" (result) 153 :"=&r" (temp), "=m" (v->counter), "=&r" (result)
152 :"Ir" (i), "m" (v->counter) : "memory"); 154 :"Ir" (i), "m" (v->counter) : "memory");
155 smp_mb();
153 return result; 156 return result;
154} 157}
155 158
156static __inline__ long atomic64_sub_return(long i, atomic64_t * v) 159static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
157{ 160{
158 long temp, result; 161 long temp, result;
162 smp_mb();
159 __asm__ __volatile__( 163 __asm__ __volatile__(
160 "1: ldq_l %0,%1\n" 164 "1: ldq_l %0,%1\n"
161 " subq %0,%3,%2\n" 165 " subq %0,%3,%2\n"
162 " subq %0,%3,%0\n" 166 " subq %0,%3,%0\n"
163 " stq_c %0,%1\n" 167 " stq_c %0,%1\n"
164 " beq %0,2f\n" 168 " beq %0,2f\n"
165 " mb\n"
166 ".subsection 2\n" 169 ".subsection 2\n"
167 "2: br 1b\n" 170 "2: br 1b\n"
168 ".previous" 171 ".previous"
169 :"=&r" (temp), "=m" (v->counter), "=&r" (result) 172 :"=&r" (temp), "=m" (v->counter), "=&r" (result)
170 :"Ir" (i), "m" (v->counter) : "memory"); 173 :"Ir" (i), "m" (v->counter) : "memory");
174 smp_mb();
171 return result; 175 return result;
172} 176}
173 177