1 /* atomic.c -- implement atomic routines for Go.
2
3 Copyright 2011 The Go Authors. All rights reserved.
4 Use of this source code is governed by a BSD-style
5 license that can be found in the LICENSE file. */
6
7 #include <stdint.h>
8
9 #include "runtime.h"
10
11 int32_t SwapInt32 (int32_t *, int32_t)
12 __asm__ (GOSYM_PREFIX "sync_atomic.SwapInt32")
13 __attribute__ ((no_split_stack));
14
15 int32_t
SwapInt32(int32_t * addr,int32_t new)16 SwapInt32 (int32_t *addr, int32_t new)
17 {
18 return __atomic_exchange_n (addr, new, __ATOMIC_SEQ_CST);
19 }
20
21 int64_t SwapInt64 (int64_t *, int64_t)
22 __asm__ (GOSYM_PREFIX "sync_atomic.SwapInt64")
23 __attribute__ ((no_split_stack));
24
25 int64_t
SwapInt64(int64_t * addr,int64_t new)26 SwapInt64 (int64_t *addr, int64_t new)
27 {
28 return __atomic_exchange_n (addr, new, __ATOMIC_SEQ_CST);
29 }
30
31 uint32_t SwapUint32 (uint32_t *, uint32_t)
32 __asm__ (GOSYM_PREFIX "sync_atomic.SwapUint32")
33 __attribute__ ((no_split_stack));
34
35 uint32_t
SwapUint32(uint32_t * addr,uint32_t new)36 SwapUint32 (uint32_t *addr, uint32_t new)
37 {
38 return __atomic_exchange_n (addr, new, __ATOMIC_SEQ_CST);
39 }
40
41 uint64_t SwapUint64 (uint64_t *, uint64_t)
42 __asm__ (GOSYM_PREFIX "sync_atomic.SwapUint64")
43 __attribute__ ((no_split_stack));
44
45 uint64_t
SwapUint64(uint64_t * addr,uint64_t new)46 SwapUint64 (uint64_t *addr, uint64_t new)
47 {
48 return __atomic_exchange_n (addr, new, __ATOMIC_SEQ_CST);
49 }
50
51 uintptr_t SwapUintptr (uintptr_t *, uintptr_t)
52 __asm__ (GOSYM_PREFIX "sync_atomic.SwapUintptr")
53 __attribute__ ((no_split_stack));
54
55 uintptr_t
SwapUintptr(uintptr_t * addr,uintptr_t new)56 SwapUintptr (uintptr_t *addr, uintptr_t new)
57 {
58 return __atomic_exchange_n (addr, new, __ATOMIC_SEQ_CST);
59 }
60
61 void *SwapPointer (void **, void *)
62 __asm__ (GOSYM_PREFIX "sync_atomic.SwapPointer")
63 __attribute__ ((no_split_stack));
64
65 void *
SwapPointer(void ** addr,void * new)66 SwapPointer (void **addr, void *new)
67 {
68 return __atomic_exchange_n (addr, new, __ATOMIC_SEQ_CST);
69 }
70
71 _Bool CompareAndSwapInt32 (int32_t *, int32_t, int32_t)
72 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapInt32")
73 __attribute__ ((no_split_stack));
74
75 _Bool
CompareAndSwapInt32(int32_t * val,int32_t old,int32_t new)76 CompareAndSwapInt32 (int32_t *val, int32_t old, int32_t new)
77 {
78 return __sync_bool_compare_and_swap (val, old, new);
79 }
80
81 _Bool CompareAndSwapInt64 (int64_t *, int64_t, int64_t)
82 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapInt64")
83 __attribute__ ((no_split_stack));
84
85 _Bool
CompareAndSwapInt64(int64_t * val,int64_t old,int64_t new)86 CompareAndSwapInt64 (int64_t *val, int64_t old, int64_t new)
87 {
88 return __sync_bool_compare_and_swap (val, old, new);
89 }
90
91 _Bool CompareAndSwapUint32 (uint32_t *, uint32_t, uint32_t)
92 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapUint32")
93 __attribute__ ((no_split_stack));
94
95 _Bool
CompareAndSwapUint32(uint32_t * val,uint32_t old,uint32_t new)96 CompareAndSwapUint32 (uint32_t *val, uint32_t old, uint32_t new)
97 {
98 return __sync_bool_compare_and_swap (val, old, new);
99 }
100
101 _Bool CompareAndSwapUint64 (uint64_t *, uint64_t, uint64_t)
102 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapUint64")
103 __attribute__ ((no_split_stack));
104
105 _Bool
CompareAndSwapUint64(uint64_t * val,uint64_t old,uint64_t new)106 CompareAndSwapUint64 (uint64_t *val, uint64_t old, uint64_t new)
107 {
108 return __sync_bool_compare_and_swap (val, old, new);
109 }
110
111 _Bool CompareAndSwapUintptr (uintptr_t *, uintptr_t, uintptr_t)
112 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapUintptr")
113 __attribute__ ((no_split_stack));
114
115 _Bool
CompareAndSwapUintptr(uintptr_t * val,uintptr_t old,uintptr_t new)116 CompareAndSwapUintptr (uintptr_t *val, uintptr_t old, uintptr_t new)
117 {
118 return __sync_bool_compare_and_swap (val, old, new);
119 }
120
121 _Bool CompareAndSwapPointer (void **, void *, void *)
122 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapPointer")
123 __attribute__ ((no_split_stack));
124
125 _Bool
CompareAndSwapPointer(void ** val,void * old,void * new)126 CompareAndSwapPointer (void **val, void *old, void *new)
127 {
128 return __sync_bool_compare_and_swap (val, old, new);
129 }
130
131 int32_t AddInt32 (int32_t *, int32_t)
132 __asm__ (GOSYM_PREFIX "sync_atomic.AddInt32")
133 __attribute__ ((no_split_stack));
134
135 int32_t
AddInt32(int32_t * val,int32_t delta)136 AddInt32 (int32_t *val, int32_t delta)
137 {
138 return __sync_add_and_fetch (val, delta);
139 }
140
141 uint32_t AddUint32 (uint32_t *, uint32_t)
142 __asm__ (GOSYM_PREFIX "sync_atomic.AddUint32")
143 __attribute__ ((no_split_stack));
144
145 uint32_t
AddUint32(uint32_t * val,uint32_t delta)146 AddUint32 (uint32_t *val, uint32_t delta)
147 {
148 return __sync_add_and_fetch (val, delta);
149 }
150
151 int64_t AddInt64 (int64_t *, int64_t)
152 __asm__ (GOSYM_PREFIX "sync_atomic.AddInt64")
153 __attribute__ ((no_split_stack));
154
155 int64_t
AddInt64(int64_t * val,int64_t delta)156 AddInt64 (int64_t *val, int64_t delta)
157 {
158 return __sync_add_and_fetch (val, delta);
159 }
160
161 uint64_t AddUint64 (uint64_t *, uint64_t)
162 __asm__ (GOSYM_PREFIX "sync_atomic.AddUint64")
163 __attribute__ ((no_split_stack));
164
165 uint64_t
AddUint64(uint64_t * val,uint64_t delta)166 AddUint64 (uint64_t *val, uint64_t delta)
167 {
168 return __sync_add_and_fetch (val, delta);
169 }
170
171 uintptr_t AddUintptr (uintptr_t *, uintptr_t)
172 __asm__ (GOSYM_PREFIX "sync_atomic.AddUintptr")
173 __attribute__ ((no_split_stack));
174
175 uintptr_t
AddUintptr(uintptr_t * val,uintptr_t delta)176 AddUintptr (uintptr_t *val, uintptr_t delta)
177 {
178 return __sync_add_and_fetch (val, delta);
179 }
180
181 int32_t LoadInt32 (int32_t *addr)
182 __asm__ (GOSYM_PREFIX "sync_atomic.LoadInt32")
183 __attribute__ ((no_split_stack));
184
185 int32_t
LoadInt32(int32_t * addr)186 LoadInt32 (int32_t *addr)
187 {
188 int32_t v;
189
190 v = *addr;
191 while (! __sync_bool_compare_and_swap (addr, v, v))
192 v = *addr;
193 return v;
194 }
195
196 int64_t LoadInt64 (int64_t *addr)
197 __asm__ (GOSYM_PREFIX "sync_atomic.LoadInt64")
198 __attribute__ ((no_split_stack));
199
200 int64_t
LoadInt64(int64_t * addr)201 LoadInt64 (int64_t *addr)
202 {
203 int64_t v;
204
205 v = *addr;
206 while (! __sync_bool_compare_and_swap (addr, v, v))
207 v = *addr;
208 return v;
209 }
210
211 uint32_t LoadUint32 (uint32_t *addr)
212 __asm__ (GOSYM_PREFIX "sync_atomic.LoadUint32")
213 __attribute__ ((no_split_stack));
214
215 uint32_t
LoadUint32(uint32_t * addr)216 LoadUint32 (uint32_t *addr)
217 {
218 uint32_t v;
219
220 v = *addr;
221 while (! __sync_bool_compare_and_swap (addr, v, v))
222 v = *addr;
223 return v;
224 }
225
226 uint64_t LoadUint64 (uint64_t *addr)
227 __asm__ (GOSYM_PREFIX "sync_atomic.LoadUint64")
228 __attribute__ ((no_split_stack));
229
230 uint64_t
LoadUint64(uint64_t * addr)231 LoadUint64 (uint64_t *addr)
232 {
233 uint64_t v;
234
235 v = *addr;
236 while (! __sync_bool_compare_and_swap (addr, v, v))
237 v = *addr;
238 return v;
239 }
240
241 uintptr_t LoadUintptr (uintptr_t *addr)
242 __asm__ (GOSYM_PREFIX "sync_atomic.LoadUintptr")
243 __attribute__ ((no_split_stack));
244
245 uintptr_t
LoadUintptr(uintptr_t * addr)246 LoadUintptr (uintptr_t *addr)
247 {
248 uintptr_t v;
249
250 v = *addr;
251 while (! __sync_bool_compare_and_swap (addr, v, v))
252 v = *addr;
253 return v;
254 }
255
256 void *LoadPointer (void **addr)
257 __asm__ (GOSYM_PREFIX "sync_atomic.LoadPointer")
258 __attribute__ ((no_split_stack));
259
260 void *
LoadPointer(void ** addr)261 LoadPointer (void **addr)
262 {
263 void *v;
264
265 v = *addr;
266 while (! __sync_bool_compare_and_swap (addr, v, v))
267 v = *addr;
268 return v;
269 }
270
271 void StoreInt32 (int32_t *addr, int32_t val)
272 __asm__ (GOSYM_PREFIX "sync_atomic.StoreInt32")
273 __attribute__ ((no_split_stack));
274
275 void
StoreInt32(int32_t * addr,int32_t val)276 StoreInt32 (int32_t *addr, int32_t val)
277 {
278 int32_t v;
279
280 v = *addr;
281 while (! __sync_bool_compare_and_swap (addr, v, val))
282 v = *addr;
283 }
284
285 void StoreInt64 (int64_t *addr, int64_t val)
286 __asm__ (GOSYM_PREFIX "sync_atomic.StoreInt64")
287 __attribute__ ((no_split_stack));
288
289 void
StoreInt64(int64_t * addr,int64_t val)290 StoreInt64 (int64_t *addr, int64_t val)
291 {
292 int64_t v;
293
294 v = *addr;
295 while (! __sync_bool_compare_and_swap (addr, v, val))
296 v = *addr;
297 }
298
299 void StoreUint32 (uint32_t *addr, uint32_t val)
300 __asm__ (GOSYM_PREFIX "sync_atomic.StoreUint32")
301 __attribute__ ((no_split_stack));
302
303 void
StoreUint32(uint32_t * addr,uint32_t val)304 StoreUint32 (uint32_t *addr, uint32_t val)
305 {
306 uint32_t v;
307
308 v = *addr;
309 while (! __sync_bool_compare_and_swap (addr, v, val))
310 v = *addr;
311 }
312
313 void StoreUint64 (uint64_t *addr, uint64_t val)
314 __asm__ (GOSYM_PREFIX "sync_atomic.StoreUint64")
315 __attribute__ ((no_split_stack));
316
317 void
StoreUint64(uint64_t * addr,uint64_t val)318 StoreUint64 (uint64_t *addr, uint64_t val)
319 {
320 uint64_t v;
321
322 v = *addr;
323 while (! __sync_bool_compare_and_swap (addr, v, val))
324 v = *addr;
325 }
326
327 void StoreUintptr (uintptr_t *addr, uintptr_t val)
328 __asm__ (GOSYM_PREFIX "sync_atomic.StoreUintptr")
329 __attribute__ ((no_split_stack));
330
331 void
StoreUintptr(uintptr_t * addr,uintptr_t val)332 StoreUintptr (uintptr_t *addr, uintptr_t val)
333 {
334 uintptr_t v;
335
336 v = *addr;
337 while (! __sync_bool_compare_and_swap (addr, v, val))
338 v = *addr;
339 }
340
341 void StorePointer (void **addr, void *val)
342 __asm__ (GOSYM_PREFIX "sync_atomic.StorePointer")
343 __attribute__ ((no_split_stack));
344
345 void
StorePointer(void ** addr,void * val)346 StorePointer (void **addr, void *val)
347 {
348 void *v;
349
350 v = *addr;
351 while (! __sync_bool_compare_and_swap (addr, v, val))
352 v = *addr;
353 }
354