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 _Bool CompareAndSwapInt32 (int32_t *, int32_t, int32_t)
12 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapInt32");
13
14 _Bool
CompareAndSwapInt32(int32_t * val,int32_t old,int32_t new)15 CompareAndSwapInt32 (int32_t *val, int32_t old, int32_t new)
16 {
17 return __sync_bool_compare_and_swap (val, old, new);
18 }
19
20 _Bool CompareAndSwapInt64 (int64_t *, int64_t, int64_t)
21 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapInt64");
22
23 _Bool
CompareAndSwapInt64(int64_t * val,int64_t old,int64_t new)24 CompareAndSwapInt64 (int64_t *val, int64_t old, int64_t new)
25 {
26 return __sync_bool_compare_and_swap (val, old, new);
27 }
28
29 _Bool CompareAndSwapUint32 (uint32_t *, uint32_t, uint32_t)
30 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapUint32");
31
32 _Bool
CompareAndSwapUint32(uint32_t * val,uint32_t old,uint32_t new)33 CompareAndSwapUint32 (uint32_t *val, uint32_t old, uint32_t new)
34 {
35 return __sync_bool_compare_and_swap (val, old, new);
36 }
37
38 _Bool CompareAndSwapUint64 (uint64_t *, uint64_t, uint64_t)
39 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapUint64");
40
41 _Bool
CompareAndSwapUint64(uint64_t * val,uint64_t old,uint64_t new)42 CompareAndSwapUint64 (uint64_t *val, uint64_t old, uint64_t new)
43 {
44 return __sync_bool_compare_and_swap (val, old, new);
45 }
46
47 _Bool CompareAndSwapUintptr (uintptr_t *, uintptr_t, uintptr_t)
48 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapUintptr");
49
50 _Bool
CompareAndSwapUintptr(uintptr_t * val,uintptr_t old,uintptr_t new)51 CompareAndSwapUintptr (uintptr_t *val, uintptr_t old, uintptr_t new)
52 {
53 return __sync_bool_compare_and_swap (val, old, new);
54 }
55
56 _Bool CompareAndSwapPointer (void **, void *, void *)
57 __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapPointer");
58
59 _Bool
CompareAndSwapPointer(void ** val,void * old,void * new)60 CompareAndSwapPointer (void **val, void *old, void *new)
61 {
62 return __sync_bool_compare_and_swap (val, old, new);
63 }
64
65 int32_t AddInt32 (int32_t *, int32_t)
66 __asm__ (GOSYM_PREFIX "sync_atomic.AddInt32");
67
68 int32_t
AddInt32(int32_t * val,int32_t delta)69 AddInt32 (int32_t *val, int32_t delta)
70 {
71 return __sync_add_and_fetch (val, delta);
72 }
73
74 uint32_t AddUint32 (uint32_t *, uint32_t)
75 __asm__ (GOSYM_PREFIX "sync_atomic.AddUint32");
76
77 uint32_t
AddUint32(uint32_t * val,uint32_t delta)78 AddUint32 (uint32_t *val, uint32_t delta)
79 {
80 return __sync_add_and_fetch (val, delta);
81 }
82
83 int64_t AddInt64 (int64_t *, int64_t)
84 __asm__ (GOSYM_PREFIX "sync_atomic.AddInt64");
85
86 int64_t
AddInt64(int64_t * val,int64_t delta)87 AddInt64 (int64_t *val, int64_t delta)
88 {
89 return __sync_add_and_fetch (val, delta);
90 }
91
92 uint64_t AddUint64 (uint64_t *, uint64_t)
93 __asm__ (GOSYM_PREFIX "sync_atomic.AddUint64");
94
95 uint64_t
AddUint64(uint64_t * val,uint64_t delta)96 AddUint64 (uint64_t *val, uint64_t delta)
97 {
98 return __sync_add_and_fetch (val, delta);
99 }
100
101 uintptr_t AddUintptr (uintptr_t *, uintptr_t)
102 __asm__ (GOSYM_PREFIX "sync_atomic.AddUintptr");
103
104 uintptr_t
AddUintptr(uintptr_t * val,uintptr_t delta)105 AddUintptr (uintptr_t *val, uintptr_t delta)
106 {
107 return __sync_add_and_fetch (val, delta);
108 }
109
110 int32_t LoadInt32 (int32_t *addr)
111 __asm__ (GOSYM_PREFIX "sync_atomic.LoadInt32");
112
113 int32_t
LoadInt32(int32_t * addr)114 LoadInt32 (int32_t *addr)
115 {
116 int32_t v;
117
118 v = *addr;
119 while (! __sync_bool_compare_and_swap (addr, v, v))
120 v = *addr;
121 return v;
122 }
123
124 int64_t LoadInt64 (int64_t *addr)
125 __asm__ (GOSYM_PREFIX "sync_atomic.LoadInt64");
126
127 int64_t
LoadInt64(int64_t * addr)128 LoadInt64 (int64_t *addr)
129 {
130 int64_t v;
131
132 v = *addr;
133 while (! __sync_bool_compare_and_swap (addr, v, v))
134 v = *addr;
135 return v;
136 }
137
138 uint32_t LoadUint32 (uint32_t *addr)
139 __asm__ (GOSYM_PREFIX "sync_atomic.LoadUint32");
140
141 uint32_t
LoadUint32(uint32_t * addr)142 LoadUint32 (uint32_t *addr)
143 {
144 uint32_t v;
145
146 v = *addr;
147 while (! __sync_bool_compare_and_swap (addr, v, v))
148 v = *addr;
149 return v;
150 }
151
152 uint64_t LoadUint64 (uint64_t *addr)
153 __asm__ (GOSYM_PREFIX "sync_atomic.LoadUint64");
154
155 uint64_t
LoadUint64(uint64_t * addr)156 LoadUint64 (uint64_t *addr)
157 {
158 uint64_t v;
159
160 v = *addr;
161 while (! __sync_bool_compare_and_swap (addr, v, v))
162 v = *addr;
163 return v;
164 }
165
166 uintptr_t LoadUintptr (uintptr_t *addr)
167 __asm__ (GOSYM_PREFIX "sync_atomic.LoadUintptr");
168
169 uintptr_t
LoadUintptr(uintptr_t * addr)170 LoadUintptr (uintptr_t *addr)
171 {
172 uintptr_t v;
173
174 v = *addr;
175 while (! __sync_bool_compare_and_swap (addr, v, v))
176 v = *addr;
177 return v;
178 }
179
180 void *LoadPointer (void **addr)
181 __asm__ (GOSYM_PREFIX "sync_atomic.LoadPointer");
182
183 void *
LoadPointer(void ** addr)184 LoadPointer (void **addr)
185 {
186 void *v;
187
188 v = *addr;
189 while (! __sync_bool_compare_and_swap (addr, v, v))
190 v = *addr;
191 return v;
192 }
193
194 void StoreInt32 (int32_t *addr, int32_t val)
195 __asm__ (GOSYM_PREFIX "sync_atomic.StoreInt32");
196
197 void
StoreInt32(int32_t * addr,int32_t val)198 StoreInt32 (int32_t *addr, int32_t val)
199 {
200 int32_t v;
201
202 v = *addr;
203 while (! __sync_bool_compare_and_swap (addr, v, val))
204 v = *addr;
205 }
206
207 void StoreInt64 (int64_t *addr, int64_t val)
208 __asm__ (GOSYM_PREFIX "sync_atomic.StoreInt64");
209
210 void
StoreInt64(int64_t * addr,int64_t val)211 StoreInt64 (int64_t *addr, int64_t val)
212 {
213 int64_t v;
214
215 v = *addr;
216 while (! __sync_bool_compare_and_swap (addr, v, val))
217 v = *addr;
218 }
219
220 void StoreUint32 (uint32_t *addr, uint32_t val)
221 __asm__ (GOSYM_PREFIX "sync_atomic.StoreUint32");
222
223 void
StoreUint32(uint32_t * addr,uint32_t val)224 StoreUint32 (uint32_t *addr, uint32_t val)
225 {
226 uint32_t v;
227
228 v = *addr;
229 while (! __sync_bool_compare_and_swap (addr, v, val))
230 v = *addr;
231 }
232
233 void StoreUint64 (uint64_t *addr, uint64_t val)
234 __asm__ (GOSYM_PREFIX "sync_atomic.StoreUint64");
235
236 void
StoreUint64(uint64_t * addr,uint64_t val)237 StoreUint64 (uint64_t *addr, uint64_t val)
238 {
239 uint64_t v;
240
241 v = *addr;
242 while (! __sync_bool_compare_and_swap (addr, v, val))
243 v = *addr;
244 }
245
246 void StoreUintptr (uintptr_t *addr, uintptr_t val)
247 __asm__ (GOSYM_PREFIX "sync_atomic.StoreUintptr");
248
249 void
StoreUintptr(uintptr_t * addr,uintptr_t val)250 StoreUintptr (uintptr_t *addr, uintptr_t val)
251 {
252 uintptr_t v;
253
254 v = *addr;
255 while (! __sync_bool_compare_and_swap (addr, v, val))
256 v = *addr;
257 }
258
259 void StorePointer (void **addr, void *val)
260 __asm__ (GOSYM_PREFIX "sync_atomic.StorePointer");
261
262 void
StorePointer(void ** addr,void * val)263 StorePointer (void **addr, void *val)
264 {
265 void *v;
266
267 v = *addr;
268 while (! __sync_bool_compare_and_swap (addr, v, val))
269 v = *addr;
270 }
271