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