1 // This is the implementation of Python atomic operations using GCC's built-in
2 // functions that match the C+11 memory model. This implementation is preferred
3 // for GCC compatible compilers, such as Clang. These functions are available
4 // in GCC 4.8+ without needing to compile with --std=c11 or --std=gnu11.
5
6 #ifndef Py_ATOMIC_GCC_H
7 # error "this header file must not be included directly"
8 #endif
9
10
11 // --- _Py_atomic_add --------------------------------------------------------
12
13 static inline int
_Py_atomic_add_int(int * obj,int value)14 _Py_atomic_add_int(int *obj, int value)
15 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
16
17 static inline int8_t
_Py_atomic_add_int8(int8_t * obj,int8_t value)18 _Py_atomic_add_int8(int8_t *obj, int8_t value)
19 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
20
21 static inline int16_t
_Py_atomic_add_int16(int16_t * obj,int16_t value)22 _Py_atomic_add_int16(int16_t *obj, int16_t value)
23 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
24
25 static inline int32_t
_Py_atomic_add_int32(int32_t * obj,int32_t value)26 _Py_atomic_add_int32(int32_t *obj, int32_t value)
27 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
28
29 static inline int64_t
_Py_atomic_add_int64(int64_t * obj,int64_t value)30 _Py_atomic_add_int64(int64_t *obj, int64_t value)
31 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
32
33 static inline intptr_t
_Py_atomic_add_intptr(intptr_t * obj,intptr_t value)34 _Py_atomic_add_intptr(intptr_t *obj, intptr_t value)
35 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
36
37 static inline unsigned int
_Py_atomic_add_uint(unsigned int * obj,unsigned int value)38 _Py_atomic_add_uint(unsigned int *obj, unsigned int value)
39 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
40
41 static inline uint8_t
_Py_atomic_add_uint8(uint8_t * obj,uint8_t value)42 _Py_atomic_add_uint8(uint8_t *obj, uint8_t value)
43 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
44
45 static inline uint16_t
_Py_atomic_add_uint16(uint16_t * obj,uint16_t value)46 _Py_atomic_add_uint16(uint16_t *obj, uint16_t value)
47 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
48
49 static inline uint32_t
_Py_atomic_add_uint32(uint32_t * obj,uint32_t value)50 _Py_atomic_add_uint32(uint32_t *obj, uint32_t value)
51 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
52
53 static inline uint64_t
_Py_atomic_add_uint64(uint64_t * obj,uint64_t value)54 _Py_atomic_add_uint64(uint64_t *obj, uint64_t value)
55 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
56
57 static inline uintptr_t
_Py_atomic_add_uintptr(uintptr_t * obj,uintptr_t value)58 _Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value)
59 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
60
61 static inline Py_ssize_t
_Py_atomic_add_ssize(Py_ssize_t * obj,Py_ssize_t value)62 _Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value)
63 { return __atomic_fetch_add(obj, value, __ATOMIC_SEQ_CST); }
64
65
66 // --- _Py_atomic_compare_exchange -------------------------------------------
67
68 static inline int
_Py_atomic_compare_exchange_int(int * obj,int * expected,int desired)69 _Py_atomic_compare_exchange_int(int *obj, int *expected, int desired)
70 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
71 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
72
73 static inline int
_Py_atomic_compare_exchange_int8(int8_t * obj,int8_t * expected,int8_t desired)74 _Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t desired)
75 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
76 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
77
78 static inline int
_Py_atomic_compare_exchange_int16(int16_t * obj,int16_t * expected,int16_t desired)79 _Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t desired)
80 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
81 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
82
83 static inline int
_Py_atomic_compare_exchange_int32(int32_t * obj,int32_t * expected,int32_t desired)84 _Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t desired)
85 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
86 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
87
88 static inline int
_Py_atomic_compare_exchange_int64(int64_t * obj,int64_t * expected,int64_t desired)89 _Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desired)
90 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
91 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
92
93 static inline int
_Py_atomic_compare_exchange_intptr(intptr_t * obj,intptr_t * expected,intptr_t desired)94 _Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired)
95 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
96 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
97
98 static inline int
_Py_atomic_compare_exchange_uint(unsigned int * obj,unsigned int * expected,unsigned int desired)99 _Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int desired)
100 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
101 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
102
103 static inline int
_Py_atomic_compare_exchange_uint8(uint8_t * obj,uint8_t * expected,uint8_t desired)104 _Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t desired)
105 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
106 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
107
108 static inline int
_Py_atomic_compare_exchange_uint16(uint16_t * obj,uint16_t * expected,uint16_t desired)109 _Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t desired)
110 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
111 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
112
113 static inline int
_Py_atomic_compare_exchange_uint32(uint32_t * obj,uint32_t * expected,uint32_t desired)114 _Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t desired)
115 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
116 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
117
118 static inline int
_Py_atomic_compare_exchange_uint64(uint64_t * obj,uint64_t * expected,uint64_t desired)119 _Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t desired)
120 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
121 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
122
123 static inline int
_Py_atomic_compare_exchange_uintptr(uintptr_t * obj,uintptr_t * expected,uintptr_t desired)124 _Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t desired)
125 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
126 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
127
128 static inline int
_Py_atomic_compare_exchange_ssize(Py_ssize_t * obj,Py_ssize_t * expected,Py_ssize_t desired)129 _Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t desired)
130 { return __atomic_compare_exchange_n(obj, expected, desired, 0,
131 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
132
133 static inline int
_Py_atomic_compare_exchange_ptr(void * obj,void * expected,void * desired)134 _Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *desired)
135 { return __atomic_compare_exchange_n((void **)obj, (void **)expected, desired, 0,
136 __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
137
138
139 // --- _Py_atomic_exchange ---------------------------------------------------
140
141 static inline int
_Py_atomic_exchange_int(int * obj,int value)142 _Py_atomic_exchange_int(int *obj, int value)
143 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
144
145 static inline int8_t
_Py_atomic_exchange_int8(int8_t * obj,int8_t value)146 _Py_atomic_exchange_int8(int8_t *obj, int8_t value)
147 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
148
149 static inline int16_t
_Py_atomic_exchange_int16(int16_t * obj,int16_t value)150 _Py_atomic_exchange_int16(int16_t *obj, int16_t value)
151 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
152
153 static inline int32_t
_Py_atomic_exchange_int32(int32_t * obj,int32_t value)154 _Py_atomic_exchange_int32(int32_t *obj, int32_t value)
155 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
156
157 static inline int64_t
_Py_atomic_exchange_int64(int64_t * obj,int64_t value)158 _Py_atomic_exchange_int64(int64_t *obj, int64_t value)
159 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
160
161 static inline intptr_t
_Py_atomic_exchange_intptr(intptr_t * obj,intptr_t value)162 _Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value)
163 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
164
165 static inline unsigned int
_Py_atomic_exchange_uint(unsigned int * obj,unsigned int value)166 _Py_atomic_exchange_uint(unsigned int *obj, unsigned int value)
167 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
168
169 static inline uint8_t
_Py_atomic_exchange_uint8(uint8_t * obj,uint8_t value)170 _Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value)
171 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
172
173 static inline uint16_t
_Py_atomic_exchange_uint16(uint16_t * obj,uint16_t value)174 _Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value)
175 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
176
177 static inline uint32_t
_Py_atomic_exchange_uint32(uint32_t * obj,uint32_t value)178 _Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value)
179 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
180
181 static inline uint64_t
_Py_atomic_exchange_uint64(uint64_t * obj,uint64_t value)182 _Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value)
183 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
184
185 static inline uintptr_t
_Py_atomic_exchange_uintptr(uintptr_t * obj,uintptr_t value)186 _Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value)
187 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
188
189 static inline Py_ssize_t
_Py_atomic_exchange_ssize(Py_ssize_t * obj,Py_ssize_t value)190 _Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value)
191 { return __atomic_exchange_n(obj, value, __ATOMIC_SEQ_CST); }
192
193 static inline void *
_Py_atomic_exchange_ptr(void * obj,void * value)194 _Py_atomic_exchange_ptr(void *obj, void *value)
195 { return __atomic_exchange_n((void **)obj, value, __ATOMIC_SEQ_CST); }
196
197
198 // --- _Py_atomic_and --------------------------------------------------------
199
200 static inline uint8_t
_Py_atomic_and_uint8(uint8_t * obj,uint8_t value)201 _Py_atomic_and_uint8(uint8_t *obj, uint8_t value)
202 { return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
203
204 static inline uint16_t
_Py_atomic_and_uint16(uint16_t * obj,uint16_t value)205 _Py_atomic_and_uint16(uint16_t *obj, uint16_t value)
206 { return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
207
208 static inline uint32_t
_Py_atomic_and_uint32(uint32_t * obj,uint32_t value)209 _Py_atomic_and_uint32(uint32_t *obj, uint32_t value)
210 { return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
211
212 static inline uint64_t
_Py_atomic_and_uint64(uint64_t * obj,uint64_t value)213 _Py_atomic_and_uint64(uint64_t *obj, uint64_t value)
214 { return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
215
216 static inline uintptr_t
_Py_atomic_and_uintptr(uintptr_t * obj,uintptr_t value)217 _Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value)
218 { return __atomic_fetch_and(obj, value, __ATOMIC_SEQ_CST); }
219
220
221 // --- _Py_atomic_or ---------------------------------------------------------
222
223 static inline uint8_t
_Py_atomic_or_uint8(uint8_t * obj,uint8_t value)224 _Py_atomic_or_uint8(uint8_t *obj, uint8_t value)
225 { return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
226
227 static inline uint16_t
_Py_atomic_or_uint16(uint16_t * obj,uint16_t value)228 _Py_atomic_or_uint16(uint16_t *obj, uint16_t value)
229 { return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
230
231 static inline uint32_t
_Py_atomic_or_uint32(uint32_t * obj,uint32_t value)232 _Py_atomic_or_uint32(uint32_t *obj, uint32_t value)
233 { return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
234
235 static inline uint64_t
_Py_atomic_or_uint64(uint64_t * obj,uint64_t value)236 _Py_atomic_or_uint64(uint64_t *obj, uint64_t value)
237 { return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
238
239 static inline uintptr_t
_Py_atomic_or_uintptr(uintptr_t * obj,uintptr_t value)240 _Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value)
241 { return __atomic_fetch_or(obj, value, __ATOMIC_SEQ_CST); }
242
243
244 // --- _Py_atomic_load -------------------------------------------------------
245
246 static inline int
_Py_atomic_load_int(const int * obj)247 _Py_atomic_load_int(const int *obj)
248 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
249
250 static inline int8_t
_Py_atomic_load_int8(const int8_t * obj)251 _Py_atomic_load_int8(const int8_t *obj)
252 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
253
254 static inline int16_t
_Py_atomic_load_int16(const int16_t * obj)255 _Py_atomic_load_int16(const int16_t *obj)
256 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
257
258 static inline int32_t
_Py_atomic_load_int32(const int32_t * obj)259 _Py_atomic_load_int32(const int32_t *obj)
260 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
261
262 static inline int64_t
_Py_atomic_load_int64(const int64_t * obj)263 _Py_atomic_load_int64(const int64_t *obj)
264 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
265
266 static inline intptr_t
_Py_atomic_load_intptr(const intptr_t * obj)267 _Py_atomic_load_intptr(const intptr_t *obj)
268 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
269
270 static inline uint8_t
_Py_atomic_load_uint8(const uint8_t * obj)271 _Py_atomic_load_uint8(const uint8_t *obj)
272 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
273
274 static inline uint16_t
_Py_atomic_load_uint16(const uint16_t * obj)275 _Py_atomic_load_uint16(const uint16_t *obj)
276 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
277
278 static inline uint32_t
_Py_atomic_load_uint32(const uint32_t * obj)279 _Py_atomic_load_uint32(const uint32_t *obj)
280 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
281
282 static inline uint64_t
_Py_atomic_load_uint64(const uint64_t * obj)283 _Py_atomic_load_uint64(const uint64_t *obj)
284 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
285
286 static inline uintptr_t
_Py_atomic_load_uintptr(const uintptr_t * obj)287 _Py_atomic_load_uintptr(const uintptr_t *obj)
288 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
289
290 static inline unsigned int
_Py_atomic_load_uint(const unsigned int * obj)291 _Py_atomic_load_uint(const unsigned int *obj)
292 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
293
294 static inline Py_ssize_t
_Py_atomic_load_ssize(const Py_ssize_t * obj)295 _Py_atomic_load_ssize(const Py_ssize_t *obj)
296 { return __atomic_load_n(obj, __ATOMIC_SEQ_CST); }
297
298 static inline void *
_Py_atomic_load_ptr(const void * obj)299 _Py_atomic_load_ptr(const void *obj)
300 { return (void *)__atomic_load_n((void * const *)obj, __ATOMIC_SEQ_CST); }
301
302
303 // --- _Py_atomic_load_relaxed -----------------------------------------------
304
305 static inline int
_Py_atomic_load_int_relaxed(const int * obj)306 _Py_atomic_load_int_relaxed(const int *obj)
307 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
308
309 static inline int8_t
_Py_atomic_load_int8_relaxed(const int8_t * obj)310 _Py_atomic_load_int8_relaxed(const int8_t *obj)
311 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
312
313 static inline int16_t
_Py_atomic_load_int16_relaxed(const int16_t * obj)314 _Py_atomic_load_int16_relaxed(const int16_t *obj)
315 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
316
317 static inline int32_t
_Py_atomic_load_int32_relaxed(const int32_t * obj)318 _Py_atomic_load_int32_relaxed(const int32_t *obj)
319 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
320
321 static inline int64_t
_Py_atomic_load_int64_relaxed(const int64_t * obj)322 _Py_atomic_load_int64_relaxed(const int64_t *obj)
323 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
324
325 static inline intptr_t
_Py_atomic_load_intptr_relaxed(const intptr_t * obj)326 _Py_atomic_load_intptr_relaxed(const intptr_t *obj)
327 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
328
329 static inline uint8_t
_Py_atomic_load_uint8_relaxed(const uint8_t * obj)330 _Py_atomic_load_uint8_relaxed(const uint8_t *obj)
331 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
332
333 static inline uint16_t
_Py_atomic_load_uint16_relaxed(const uint16_t * obj)334 _Py_atomic_load_uint16_relaxed(const uint16_t *obj)
335 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
336
337 static inline uint32_t
_Py_atomic_load_uint32_relaxed(const uint32_t * obj)338 _Py_atomic_load_uint32_relaxed(const uint32_t *obj)
339 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
340
341 static inline uint64_t
_Py_atomic_load_uint64_relaxed(const uint64_t * obj)342 _Py_atomic_load_uint64_relaxed(const uint64_t *obj)
343 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
344
345 static inline uintptr_t
_Py_atomic_load_uintptr_relaxed(const uintptr_t * obj)346 _Py_atomic_load_uintptr_relaxed(const uintptr_t *obj)
347 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
348
349 static inline unsigned int
_Py_atomic_load_uint_relaxed(const unsigned int * obj)350 _Py_atomic_load_uint_relaxed(const unsigned int *obj)
351 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
352
353 static inline Py_ssize_t
_Py_atomic_load_ssize_relaxed(const Py_ssize_t * obj)354 _Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj)
355 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
356
357 static inline void *
_Py_atomic_load_ptr_relaxed(const void * obj)358 _Py_atomic_load_ptr_relaxed(const void *obj)
359 { return (void *)__atomic_load_n((void * const *)obj, __ATOMIC_RELAXED); }
360
361 static inline unsigned long long
_Py_atomic_load_ullong_relaxed(const unsigned long long * obj)362 _Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
363 { return __atomic_load_n(obj, __ATOMIC_RELAXED); }
364
365
366 // --- _Py_atomic_store ------------------------------------------------------
367
368 static inline void
_Py_atomic_store_int(int * obj,int value)369 _Py_atomic_store_int(int *obj, int value)
370 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
371
372 static inline void
_Py_atomic_store_int8(int8_t * obj,int8_t value)373 _Py_atomic_store_int8(int8_t *obj, int8_t value)
374 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
375
376 static inline void
_Py_atomic_store_int16(int16_t * obj,int16_t value)377 _Py_atomic_store_int16(int16_t *obj, int16_t value)
378 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
379
380 static inline void
_Py_atomic_store_int32(int32_t * obj,int32_t value)381 _Py_atomic_store_int32(int32_t *obj, int32_t value)
382 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
383
384 static inline void
_Py_atomic_store_int64(int64_t * obj,int64_t value)385 _Py_atomic_store_int64(int64_t *obj, int64_t value)
386 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
387
388 static inline void
_Py_atomic_store_intptr(intptr_t * obj,intptr_t value)389 _Py_atomic_store_intptr(intptr_t *obj, intptr_t value)
390 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
391
392 static inline void
_Py_atomic_store_uint8(uint8_t * obj,uint8_t value)393 _Py_atomic_store_uint8(uint8_t *obj, uint8_t value)
394 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
395
396 static inline void
_Py_atomic_store_uint16(uint16_t * obj,uint16_t value)397 _Py_atomic_store_uint16(uint16_t *obj, uint16_t value)
398 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
399
400 static inline void
_Py_atomic_store_uint32(uint32_t * obj,uint32_t value)401 _Py_atomic_store_uint32(uint32_t *obj, uint32_t value)
402 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
403
404 static inline void
_Py_atomic_store_uint64(uint64_t * obj,uint64_t value)405 _Py_atomic_store_uint64(uint64_t *obj, uint64_t value)
406 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
407
408 static inline void
_Py_atomic_store_uintptr(uintptr_t * obj,uintptr_t value)409 _Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value)
410 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
411
412 static inline void
_Py_atomic_store_uint(unsigned int * obj,unsigned int value)413 _Py_atomic_store_uint(unsigned int *obj, unsigned int value)
414 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
415
416 static inline void
_Py_atomic_store_ptr(void * obj,void * value)417 _Py_atomic_store_ptr(void *obj, void *value)
418 { __atomic_store_n((void **)obj, value, __ATOMIC_SEQ_CST); }
419
420 static inline void
_Py_atomic_store_ssize(Py_ssize_t * obj,Py_ssize_t value)421 _Py_atomic_store_ssize(Py_ssize_t *obj, Py_ssize_t value)
422 { __atomic_store_n(obj, value, __ATOMIC_SEQ_CST); }
423
424
425 // --- _Py_atomic_store_relaxed ----------------------------------------------
426
427 static inline void
_Py_atomic_store_int_relaxed(int * obj,int value)428 _Py_atomic_store_int_relaxed(int *obj, int value)
429 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
430
431 static inline void
_Py_atomic_store_int8_relaxed(int8_t * obj,int8_t value)432 _Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value)
433 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
434
435 static inline void
_Py_atomic_store_int16_relaxed(int16_t * obj,int16_t value)436 _Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value)
437 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
438
439 static inline void
_Py_atomic_store_int32_relaxed(int32_t * obj,int32_t value)440 _Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value)
441 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
442
443 static inline void
_Py_atomic_store_int64_relaxed(int64_t * obj,int64_t value)444 _Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value)
445 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
446
447 static inline void
_Py_atomic_store_intptr_relaxed(intptr_t * obj,intptr_t value)448 _Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value)
449 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
450
451 static inline void
_Py_atomic_store_uint8_relaxed(uint8_t * obj,uint8_t value)452 _Py_atomic_store_uint8_relaxed(uint8_t *obj, uint8_t value)
453 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
454
455 static inline void
_Py_atomic_store_uint16_relaxed(uint16_t * obj,uint16_t value)456 _Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value)
457 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
458
459 static inline void
_Py_atomic_store_uint32_relaxed(uint32_t * obj,uint32_t value)460 _Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value)
461 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
462
463 static inline void
_Py_atomic_store_uint64_relaxed(uint64_t * obj,uint64_t value)464 _Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value)
465 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
466
467 static inline void
_Py_atomic_store_uintptr_relaxed(uintptr_t * obj,uintptr_t value)468 _Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value)
469 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
470
471 static inline void
_Py_atomic_store_uint_relaxed(unsigned int * obj,unsigned int value)472 _Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value)
473 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
474
475 static inline void
_Py_atomic_store_ptr_relaxed(void * obj,void * value)476 _Py_atomic_store_ptr_relaxed(void *obj, void *value)
477 { __atomic_store_n((void **)obj, value, __ATOMIC_RELAXED); }
478
479 static inline void
_Py_atomic_store_ssize_relaxed(Py_ssize_t * obj,Py_ssize_t value)480 _Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value)
481 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
482
483 static inline void
_Py_atomic_store_ullong_relaxed(unsigned long long * obj,unsigned long long value)484 _Py_atomic_store_ullong_relaxed(unsigned long long *obj,
485 unsigned long long value)
486 { __atomic_store_n(obj, value, __ATOMIC_RELAXED); }
487
488
489 // --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------
490
491 static inline void *
_Py_atomic_load_ptr_acquire(const void * obj)492 _Py_atomic_load_ptr_acquire(const void *obj)
493 { return (void *)__atomic_load_n((void * const *)obj, __ATOMIC_ACQUIRE); }
494
495 static inline uintptr_t
_Py_atomic_load_uintptr_acquire(const uintptr_t * obj)496 _Py_atomic_load_uintptr_acquire(const uintptr_t *obj)
497 { return (uintptr_t)__atomic_load_n(obj, __ATOMIC_ACQUIRE); }
498
499 static inline void
_Py_atomic_store_ptr_release(void * obj,void * value)500 _Py_atomic_store_ptr_release(void *obj, void *value)
501 { __atomic_store_n((void **)obj, value, __ATOMIC_RELEASE); }
502
503 static inline void
_Py_atomic_store_uintptr_release(uintptr_t * obj,uintptr_t value)504 _Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value)
505 { __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
506
507 static inline void
_Py_atomic_store_int_release(int * obj,int value)508 _Py_atomic_store_int_release(int *obj, int value)
509 { __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
510
511 static inline void
_Py_atomic_store_ssize_release(Py_ssize_t * obj,Py_ssize_t value)512 _Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
513 { __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
514
515 static inline int
_Py_atomic_load_int_acquire(const int * obj)516 _Py_atomic_load_int_acquire(const int *obj)
517 { return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
518
519 static inline void
_Py_atomic_store_uint32_release(uint32_t * obj,uint32_t value)520 _Py_atomic_store_uint32_release(uint32_t *obj, uint32_t value)
521 { __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
522
523 static inline void
_Py_atomic_store_uint64_release(uint64_t * obj,uint64_t value)524 _Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value)
525 { __atomic_store_n(obj, value, __ATOMIC_RELEASE); }
526
527 static inline uint64_t
_Py_atomic_load_uint64_acquire(const uint64_t * obj)528 _Py_atomic_load_uint64_acquire(const uint64_t *obj)
529 { return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
530
531 static inline uint32_t
_Py_atomic_load_uint32_acquire(const uint32_t * obj)532 _Py_atomic_load_uint32_acquire(const uint32_t *obj)
533 { return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
534
535 static inline Py_ssize_t
_Py_atomic_load_ssize_acquire(const Py_ssize_t * obj)536 _Py_atomic_load_ssize_acquire(const Py_ssize_t *obj)
537 { return __atomic_load_n(obj, __ATOMIC_ACQUIRE); }
538
539 // --- _Py_atomic_fence ------------------------------------------------------
540
541 static inline void
_Py_atomic_fence_seq_cst(void)542 _Py_atomic_fence_seq_cst(void)
543 { __atomic_thread_fence(__ATOMIC_SEQ_CST); }
544
545 static inline void
_Py_atomic_fence_acquire(void)546 _Py_atomic_fence_acquire(void)
547 { __atomic_thread_fence(__ATOMIC_ACQUIRE); }
548
549 static inline void
_Py_atomic_fence_release(void)550 _Py_atomic_fence_release(void)
551 { __atomic_thread_fence(__ATOMIC_RELEASE); }
552