• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // This is the implementation of Python atomic operations using C++11 or C11
2 // atomics. Note that the pyatomic_gcc.h implementation is preferred for GCC
3 // compatible compilers, even if they support C++11 atomics.
4 
5 #ifndef Py_ATOMIC_STD_H
6 #  error "this header file must not be included directly"
7 #endif
8 
9 #ifdef __cplusplus
10 extern "C++" {
11 #  include <atomic>
12 }
13 #  define _Py_USING_STD using namespace std
14 #  define _Atomic(tp) atomic<tp>
15 #else
16 #  define  _Py_USING_STD
17 #  include <stdatomic.h>
18 #endif
19 
20 
21 // --- _Py_atomic_add --------------------------------------------------------
22 
23 static inline int
_Py_atomic_add_int(int * obj,int value)24 _Py_atomic_add_int(int *obj, int value)
25 {
26     _Py_USING_STD;
27     return atomic_fetch_add((_Atomic(int)*)obj, value);
28 }
29 
30 static inline int8_t
_Py_atomic_add_int8(int8_t * obj,int8_t value)31 _Py_atomic_add_int8(int8_t *obj, int8_t value)
32 {
33     _Py_USING_STD;
34     return atomic_fetch_add((_Atomic(int8_t)*)obj, value);
35 }
36 
37 static inline int16_t
_Py_atomic_add_int16(int16_t * obj,int16_t value)38 _Py_atomic_add_int16(int16_t *obj, int16_t value)
39 {
40     _Py_USING_STD;
41     return atomic_fetch_add((_Atomic(int16_t)*)obj, value);
42 }
43 
44 static inline int32_t
_Py_atomic_add_int32(int32_t * obj,int32_t value)45 _Py_atomic_add_int32(int32_t *obj, int32_t value)
46 {
47     _Py_USING_STD;
48     return atomic_fetch_add((_Atomic(int32_t)*)obj, value);
49 }
50 
51 static inline int64_t
_Py_atomic_add_int64(int64_t * obj,int64_t value)52 _Py_atomic_add_int64(int64_t *obj, int64_t value)
53 {
54     _Py_USING_STD;
55     return atomic_fetch_add((_Atomic(int64_t)*)obj, value);
56 }
57 
58 static inline intptr_t
_Py_atomic_add_intptr(intptr_t * obj,intptr_t value)59 _Py_atomic_add_intptr(intptr_t *obj, intptr_t value)
60 {
61     _Py_USING_STD;
62     return atomic_fetch_add((_Atomic(intptr_t)*)obj, value);
63 }
64 
65 static inline unsigned int
_Py_atomic_add_uint(unsigned int * obj,unsigned int value)66 _Py_atomic_add_uint(unsigned int *obj, unsigned int value)
67 {
68     _Py_USING_STD;
69     return atomic_fetch_add((_Atomic(unsigned int)*)obj, value);
70 }
71 
72 static inline uint8_t
_Py_atomic_add_uint8(uint8_t * obj,uint8_t value)73 _Py_atomic_add_uint8(uint8_t *obj, uint8_t value)
74 {
75     _Py_USING_STD;
76     return atomic_fetch_add((_Atomic(uint8_t)*)obj, value);
77 }
78 
79 static inline uint16_t
_Py_atomic_add_uint16(uint16_t * obj,uint16_t value)80 _Py_atomic_add_uint16(uint16_t *obj, uint16_t value)
81 {
82     _Py_USING_STD;
83     return atomic_fetch_add((_Atomic(uint16_t)*)obj, value);
84 }
85 
86 static inline uint32_t
_Py_atomic_add_uint32(uint32_t * obj,uint32_t value)87 _Py_atomic_add_uint32(uint32_t *obj, uint32_t value)
88 {
89     _Py_USING_STD;
90     return atomic_fetch_add((_Atomic(uint32_t)*)obj, value);
91 }
92 
93 static inline uint64_t
_Py_atomic_add_uint64(uint64_t * obj,uint64_t value)94 _Py_atomic_add_uint64(uint64_t *obj, uint64_t value)
95 {
96     _Py_USING_STD;
97     return atomic_fetch_add((_Atomic(uint64_t)*)obj, value);
98 }
99 
100 static inline uintptr_t
_Py_atomic_add_uintptr(uintptr_t * obj,uintptr_t value)101 _Py_atomic_add_uintptr(uintptr_t *obj, uintptr_t value)
102 {
103     _Py_USING_STD;
104     return atomic_fetch_add((_Atomic(uintptr_t)*)obj, value);
105 }
106 
107 static inline Py_ssize_t
_Py_atomic_add_ssize(Py_ssize_t * obj,Py_ssize_t value)108 _Py_atomic_add_ssize(Py_ssize_t *obj, Py_ssize_t value)
109 {
110     _Py_USING_STD;
111     return atomic_fetch_add((_Atomic(Py_ssize_t)*)obj, value);
112 }
113 
114 
115 // --- _Py_atomic_compare_exchange -------------------------------------------
116 
117 static inline int
_Py_atomic_compare_exchange_int(int * obj,int * expected,int desired)118 _Py_atomic_compare_exchange_int(int *obj, int *expected, int desired)
119 {
120     _Py_USING_STD;
121     return atomic_compare_exchange_strong((_Atomic(int)*)obj,
122                                           expected, desired);
123 }
124 
125 static inline int
_Py_atomic_compare_exchange_int8(int8_t * obj,int8_t * expected,int8_t desired)126 _Py_atomic_compare_exchange_int8(int8_t *obj, int8_t *expected, int8_t desired)
127 {
128     _Py_USING_STD;
129     return atomic_compare_exchange_strong((_Atomic(int8_t)*)obj,
130                                           expected, desired);
131 }
132 
133 static inline int
_Py_atomic_compare_exchange_int16(int16_t * obj,int16_t * expected,int16_t desired)134 _Py_atomic_compare_exchange_int16(int16_t *obj, int16_t *expected, int16_t desired)
135 {
136     _Py_USING_STD;
137     return atomic_compare_exchange_strong((_Atomic(int16_t)*)obj,
138                                           expected, desired);
139 }
140 
141 static inline int
_Py_atomic_compare_exchange_int32(int32_t * obj,int32_t * expected,int32_t desired)142 _Py_atomic_compare_exchange_int32(int32_t *obj, int32_t *expected, int32_t desired)
143 {
144     _Py_USING_STD;
145     return atomic_compare_exchange_strong((_Atomic(int32_t)*)obj,
146                                           expected, desired);
147 }
148 
149 static inline int
_Py_atomic_compare_exchange_int64(int64_t * obj,int64_t * expected,int64_t desired)150 _Py_atomic_compare_exchange_int64(int64_t *obj, int64_t *expected, int64_t desired)
151 {
152     _Py_USING_STD;
153     return atomic_compare_exchange_strong((_Atomic(int64_t)*)obj,
154                                           expected, desired);
155 }
156 
157 static inline int
_Py_atomic_compare_exchange_intptr(intptr_t * obj,intptr_t * expected,intptr_t desired)158 _Py_atomic_compare_exchange_intptr(intptr_t *obj, intptr_t *expected, intptr_t desired)
159 {
160     _Py_USING_STD;
161     return atomic_compare_exchange_strong((_Atomic(intptr_t)*)obj,
162                                           expected, desired);
163 }
164 
165 static inline int
_Py_atomic_compare_exchange_uint(unsigned int * obj,unsigned int * expected,unsigned int desired)166 _Py_atomic_compare_exchange_uint(unsigned int *obj, unsigned int *expected, unsigned int desired)
167 {
168     _Py_USING_STD;
169     return atomic_compare_exchange_strong((_Atomic(unsigned int)*)obj,
170                                           expected, desired);
171 }
172 
173 static inline int
_Py_atomic_compare_exchange_uint8(uint8_t * obj,uint8_t * expected,uint8_t desired)174 _Py_atomic_compare_exchange_uint8(uint8_t *obj, uint8_t *expected, uint8_t desired)
175 {
176     _Py_USING_STD;
177     return atomic_compare_exchange_strong((_Atomic(uint8_t)*)obj,
178                                           expected, desired);
179 }
180 
181 static inline int
_Py_atomic_compare_exchange_uint16(uint16_t * obj,uint16_t * expected,uint16_t desired)182 _Py_atomic_compare_exchange_uint16(uint16_t *obj, uint16_t *expected, uint16_t desired)
183 {
184     _Py_USING_STD;
185     return atomic_compare_exchange_strong((_Atomic(uint16_t)*)obj,
186                                           expected, desired);
187 }
188 
189 static inline int
_Py_atomic_compare_exchange_uint32(uint32_t * obj,uint32_t * expected,uint32_t desired)190 _Py_atomic_compare_exchange_uint32(uint32_t *obj, uint32_t *expected, uint32_t desired)
191 {
192     _Py_USING_STD;
193     return atomic_compare_exchange_strong((_Atomic(uint32_t)*)obj,
194                                           expected, desired);
195 }
196 
197 static inline int
_Py_atomic_compare_exchange_uint64(uint64_t * obj,uint64_t * expected,uint64_t desired)198 _Py_atomic_compare_exchange_uint64(uint64_t *obj, uint64_t *expected, uint64_t desired)
199 {
200     _Py_USING_STD;
201     return atomic_compare_exchange_strong((_Atomic(uint64_t)*)obj,
202                                           expected, desired);
203 }
204 
205 static inline int
_Py_atomic_compare_exchange_uintptr(uintptr_t * obj,uintptr_t * expected,uintptr_t desired)206 _Py_atomic_compare_exchange_uintptr(uintptr_t *obj, uintptr_t *expected, uintptr_t desired)
207 {
208     _Py_USING_STD;
209     return atomic_compare_exchange_strong((_Atomic(uintptr_t)*)obj,
210                                           expected, desired);
211 }
212 
213 static inline int
_Py_atomic_compare_exchange_ssize(Py_ssize_t * obj,Py_ssize_t * expected,Py_ssize_t desired)214 _Py_atomic_compare_exchange_ssize(Py_ssize_t *obj, Py_ssize_t *expected, Py_ssize_t desired)
215 {
216     _Py_USING_STD;
217     return atomic_compare_exchange_strong((_Atomic(Py_ssize_t)*)obj,
218                                           expected, desired);
219 }
220 
221 static inline int
_Py_atomic_compare_exchange_ptr(void * obj,void * expected,void * desired)222 _Py_atomic_compare_exchange_ptr(void *obj, void *expected, void *desired)
223 {
224     _Py_USING_STD;
225     return atomic_compare_exchange_strong((_Atomic(void *)*)obj,
226                                           (void **)expected, desired);
227 }
228 
229 
230 // --- _Py_atomic_exchange ---------------------------------------------------
231 
232 static inline int
_Py_atomic_exchange_int(int * obj,int value)233 _Py_atomic_exchange_int(int *obj, int value)
234 {
235     _Py_USING_STD;
236     return atomic_exchange((_Atomic(int)*)obj, value);
237 }
238 
239 static inline int8_t
_Py_atomic_exchange_int8(int8_t * obj,int8_t value)240 _Py_atomic_exchange_int8(int8_t *obj, int8_t value)
241 {
242     _Py_USING_STD;
243     return atomic_exchange((_Atomic(int8_t)*)obj, value);
244 }
245 
246 static inline int16_t
_Py_atomic_exchange_int16(int16_t * obj,int16_t value)247 _Py_atomic_exchange_int16(int16_t *obj, int16_t value)
248 {
249     _Py_USING_STD;
250     return atomic_exchange((_Atomic(int16_t)*)obj, value);
251 }
252 
253 static inline int32_t
_Py_atomic_exchange_int32(int32_t * obj,int32_t value)254 _Py_atomic_exchange_int32(int32_t *obj, int32_t value)
255 {
256     _Py_USING_STD;
257     return atomic_exchange((_Atomic(int32_t)*)obj, value);
258 }
259 
260 static inline int64_t
_Py_atomic_exchange_int64(int64_t * obj,int64_t value)261 _Py_atomic_exchange_int64(int64_t *obj, int64_t value)
262 {
263     _Py_USING_STD;
264     return atomic_exchange((_Atomic(int64_t)*)obj, value);
265 }
266 
267 static inline intptr_t
_Py_atomic_exchange_intptr(intptr_t * obj,intptr_t value)268 _Py_atomic_exchange_intptr(intptr_t *obj, intptr_t value)
269 {
270     _Py_USING_STD;
271     return atomic_exchange((_Atomic(intptr_t)*)obj, value);
272 }
273 
274 static inline unsigned int
_Py_atomic_exchange_uint(unsigned int * obj,unsigned int value)275 _Py_atomic_exchange_uint(unsigned int *obj, unsigned int value)
276 {
277     _Py_USING_STD;
278     return atomic_exchange((_Atomic(unsigned int)*)obj, value);
279 }
280 
281 static inline uint8_t
_Py_atomic_exchange_uint8(uint8_t * obj,uint8_t value)282 _Py_atomic_exchange_uint8(uint8_t *obj, uint8_t value)
283 {
284     _Py_USING_STD;
285     return atomic_exchange((_Atomic(uint8_t)*)obj, value);
286 }
287 
288 static inline uint16_t
_Py_atomic_exchange_uint16(uint16_t * obj,uint16_t value)289 _Py_atomic_exchange_uint16(uint16_t *obj, uint16_t value)
290 {
291     _Py_USING_STD;
292     return atomic_exchange((_Atomic(uint16_t)*)obj, value);
293 }
294 
295 static inline uint32_t
_Py_atomic_exchange_uint32(uint32_t * obj,uint32_t value)296 _Py_atomic_exchange_uint32(uint32_t *obj, uint32_t value)
297 {
298     _Py_USING_STD;
299     return atomic_exchange((_Atomic(uint32_t)*)obj, value);
300 }
301 
302 static inline uint64_t
_Py_atomic_exchange_uint64(uint64_t * obj,uint64_t value)303 _Py_atomic_exchange_uint64(uint64_t *obj, uint64_t value)
304 {
305     _Py_USING_STD;
306     return atomic_exchange((_Atomic(uint64_t)*)obj, value);
307 }
308 
309 static inline uintptr_t
_Py_atomic_exchange_uintptr(uintptr_t * obj,uintptr_t value)310 _Py_atomic_exchange_uintptr(uintptr_t *obj, uintptr_t value)
311 {
312     _Py_USING_STD;
313     return atomic_exchange((_Atomic(uintptr_t)*)obj, value);
314 }
315 
316 static inline Py_ssize_t
_Py_atomic_exchange_ssize(Py_ssize_t * obj,Py_ssize_t value)317 _Py_atomic_exchange_ssize(Py_ssize_t *obj, Py_ssize_t value)
318 {
319     _Py_USING_STD;
320     return atomic_exchange((_Atomic(Py_ssize_t)*)obj, value);
321 }
322 
323 static inline void*
_Py_atomic_exchange_ptr(void * obj,void * value)324 _Py_atomic_exchange_ptr(void *obj, void *value)
325 {
326     _Py_USING_STD;
327     return atomic_exchange((_Atomic(void *)*)obj, value);
328 }
329 
330 
331 // --- _Py_atomic_and --------------------------------------------------------
332 
333 static inline uint8_t
_Py_atomic_and_uint8(uint8_t * obj,uint8_t value)334 _Py_atomic_and_uint8(uint8_t *obj, uint8_t value)
335 {
336     _Py_USING_STD;
337     return atomic_fetch_and((_Atomic(uint8_t)*)obj, value);
338 }
339 
340 static inline uint16_t
_Py_atomic_and_uint16(uint16_t * obj,uint16_t value)341 _Py_atomic_and_uint16(uint16_t *obj, uint16_t value)
342 {
343     _Py_USING_STD;
344     return atomic_fetch_and((_Atomic(uint16_t)*)obj, value);
345 }
346 
347 static inline uint32_t
_Py_atomic_and_uint32(uint32_t * obj,uint32_t value)348 _Py_atomic_and_uint32(uint32_t *obj, uint32_t value)
349 {
350     _Py_USING_STD;
351     return atomic_fetch_and((_Atomic(uint32_t)*)obj, value);
352 }
353 
354 static inline uint64_t
_Py_atomic_and_uint64(uint64_t * obj,uint64_t value)355 _Py_atomic_and_uint64(uint64_t *obj, uint64_t value)
356 {
357     _Py_USING_STD;
358     return atomic_fetch_and((_Atomic(uint64_t)*)obj, value);
359 }
360 
361 static inline uintptr_t
_Py_atomic_and_uintptr(uintptr_t * obj,uintptr_t value)362 _Py_atomic_and_uintptr(uintptr_t *obj, uintptr_t value)
363 {
364     _Py_USING_STD;
365     return atomic_fetch_and((_Atomic(uintptr_t)*)obj, value);
366 }
367 
368 
369 // --- _Py_atomic_or ---------------------------------------------------------
370 
371 static inline uint8_t
_Py_atomic_or_uint8(uint8_t * obj,uint8_t value)372 _Py_atomic_or_uint8(uint8_t *obj, uint8_t value)
373 {
374     _Py_USING_STD;
375     return atomic_fetch_or((_Atomic(uint8_t)*)obj, value);
376 }
377 
378 static inline uint16_t
_Py_atomic_or_uint16(uint16_t * obj,uint16_t value)379 _Py_atomic_or_uint16(uint16_t *obj, uint16_t value)
380 {
381     _Py_USING_STD;
382     return atomic_fetch_or((_Atomic(uint16_t)*)obj, value);
383 }
384 
385 static inline uint32_t
_Py_atomic_or_uint32(uint32_t * obj,uint32_t value)386 _Py_atomic_or_uint32(uint32_t *obj, uint32_t value)
387 {
388     _Py_USING_STD;
389     return atomic_fetch_or((_Atomic(uint32_t)*)obj, value);
390 }
391 
392 static inline uint64_t
_Py_atomic_or_uint64(uint64_t * obj,uint64_t value)393 _Py_atomic_or_uint64(uint64_t *obj, uint64_t value)
394 {
395     _Py_USING_STD;
396     return atomic_fetch_or((_Atomic(uint64_t)*)obj, value);
397 }
398 
399 static inline uintptr_t
_Py_atomic_or_uintptr(uintptr_t * obj,uintptr_t value)400 _Py_atomic_or_uintptr(uintptr_t *obj, uintptr_t value)
401 {
402     _Py_USING_STD;
403     return atomic_fetch_or((_Atomic(uintptr_t)*)obj, value);
404 }
405 
406 
407 // --- _Py_atomic_load -------------------------------------------------------
408 
409 static inline int
_Py_atomic_load_int(const int * obj)410 _Py_atomic_load_int(const int *obj)
411 {
412     _Py_USING_STD;
413     return atomic_load((const _Atomic(int)*)obj);
414 }
415 
416 static inline int8_t
_Py_atomic_load_int8(const int8_t * obj)417 _Py_atomic_load_int8(const int8_t *obj)
418 {
419     _Py_USING_STD;
420     return atomic_load((const _Atomic(int8_t)*)obj);
421 }
422 
423 static inline int16_t
_Py_atomic_load_int16(const int16_t * obj)424 _Py_atomic_load_int16(const int16_t *obj)
425 {
426     _Py_USING_STD;
427     return atomic_load((const _Atomic(int16_t)*)obj);
428 }
429 
430 static inline int32_t
_Py_atomic_load_int32(const int32_t * obj)431 _Py_atomic_load_int32(const int32_t *obj)
432 {
433     _Py_USING_STD;
434     return atomic_load((const _Atomic(int32_t)*)obj);
435 }
436 
437 static inline int64_t
_Py_atomic_load_int64(const int64_t * obj)438 _Py_atomic_load_int64(const int64_t *obj)
439 {
440     _Py_USING_STD;
441     return atomic_load((const _Atomic(int64_t)*)obj);
442 }
443 
444 static inline intptr_t
_Py_atomic_load_intptr(const intptr_t * obj)445 _Py_atomic_load_intptr(const intptr_t *obj)
446 {
447     _Py_USING_STD;
448     return atomic_load((const _Atomic(intptr_t)*)obj);
449 }
450 
451 static inline uint8_t
_Py_atomic_load_uint8(const uint8_t * obj)452 _Py_atomic_load_uint8(const uint8_t *obj)
453 {
454     _Py_USING_STD;
455     return atomic_load((const _Atomic(uint8_t)*)obj);
456 }
457 
458 static inline uint16_t
_Py_atomic_load_uint16(const uint16_t * obj)459 _Py_atomic_load_uint16(const uint16_t *obj)
460 {
461     _Py_USING_STD;
462     return atomic_load((const _Atomic(uint32_t)*)obj);
463 }
464 
465 static inline uint32_t
_Py_atomic_load_uint32(const uint32_t * obj)466 _Py_atomic_load_uint32(const uint32_t *obj)
467 {
468     _Py_USING_STD;
469     return atomic_load((const _Atomic(uint32_t)*)obj);
470 }
471 
472 static inline uint64_t
_Py_atomic_load_uint64(const uint64_t * obj)473 _Py_atomic_load_uint64(const uint64_t *obj)
474 {
475     _Py_USING_STD;
476     return atomic_load((const _Atomic(uint64_t)*)obj);
477 }
478 
479 static inline uintptr_t
_Py_atomic_load_uintptr(const uintptr_t * obj)480 _Py_atomic_load_uintptr(const uintptr_t *obj)
481 {
482     _Py_USING_STD;
483     return atomic_load((const _Atomic(uintptr_t)*)obj);
484 }
485 
486 static inline unsigned int
_Py_atomic_load_uint(const unsigned int * obj)487 _Py_atomic_load_uint(const unsigned int *obj)
488 {
489     _Py_USING_STD;
490     return atomic_load((const _Atomic(unsigned int)*)obj);
491 }
492 
493 static inline Py_ssize_t
_Py_atomic_load_ssize(const Py_ssize_t * obj)494 _Py_atomic_load_ssize(const Py_ssize_t *obj)
495 {
496     _Py_USING_STD;
497     return atomic_load((const _Atomic(Py_ssize_t)*)obj);
498 }
499 
500 static inline void*
_Py_atomic_load_ptr(const void * obj)501 _Py_atomic_load_ptr(const void *obj)
502 {
503     _Py_USING_STD;
504     return atomic_load((const _Atomic(void*)*)obj);
505 }
506 
507 
508 // --- _Py_atomic_load_relaxed -----------------------------------------------
509 
510 static inline int
_Py_atomic_load_int_relaxed(const int * obj)511 _Py_atomic_load_int_relaxed(const int *obj)
512 {
513     _Py_USING_STD;
514     return atomic_load_explicit((const _Atomic(int)*)obj,
515                                 memory_order_relaxed);
516 }
517 
518 static inline int8_t
_Py_atomic_load_int8_relaxed(const int8_t * obj)519 _Py_atomic_load_int8_relaxed(const int8_t *obj)
520 {
521     _Py_USING_STD;
522     return atomic_load_explicit((const _Atomic(int8_t)*)obj,
523                                 memory_order_relaxed);
524 }
525 
526 static inline int16_t
_Py_atomic_load_int16_relaxed(const int16_t * obj)527 _Py_atomic_load_int16_relaxed(const int16_t *obj)
528 {
529     _Py_USING_STD;
530     return atomic_load_explicit((const _Atomic(int16_t)*)obj,
531                                 memory_order_relaxed);
532 }
533 
534 static inline int32_t
_Py_atomic_load_int32_relaxed(const int32_t * obj)535 _Py_atomic_load_int32_relaxed(const int32_t *obj)
536 {
537     _Py_USING_STD;
538     return atomic_load_explicit((const _Atomic(int32_t)*)obj,
539                                 memory_order_relaxed);
540 }
541 
542 static inline int64_t
_Py_atomic_load_int64_relaxed(const int64_t * obj)543 _Py_atomic_load_int64_relaxed(const int64_t *obj)
544 {
545     _Py_USING_STD;
546     return atomic_load_explicit((const _Atomic(int64_t)*)obj,
547                                 memory_order_relaxed);
548 }
549 
550 static inline intptr_t
_Py_atomic_load_intptr_relaxed(const intptr_t * obj)551 _Py_atomic_load_intptr_relaxed(const intptr_t *obj)
552 {
553     _Py_USING_STD;
554     return atomic_load_explicit((const _Atomic(intptr_t)*)obj,
555                                 memory_order_relaxed);
556 }
557 
558 static inline uint8_t
_Py_atomic_load_uint8_relaxed(const uint8_t * obj)559 _Py_atomic_load_uint8_relaxed(const uint8_t *obj)
560 {
561     _Py_USING_STD;
562     return atomic_load_explicit((const _Atomic(uint8_t)*)obj,
563                                 memory_order_relaxed);
564 }
565 
566 static inline uint16_t
_Py_atomic_load_uint16_relaxed(const uint16_t * obj)567 _Py_atomic_load_uint16_relaxed(const uint16_t *obj)
568 {
569     _Py_USING_STD;
570     return atomic_load_explicit((const _Atomic(uint16_t)*)obj,
571                                 memory_order_relaxed);
572 }
573 
574 static inline uint32_t
_Py_atomic_load_uint32_relaxed(const uint32_t * obj)575 _Py_atomic_load_uint32_relaxed(const uint32_t *obj)
576 {
577     _Py_USING_STD;
578     return atomic_load_explicit((const _Atomic(uint32_t)*)obj,
579                                 memory_order_relaxed);
580 }
581 
582 static inline uint64_t
_Py_atomic_load_uint64_relaxed(const uint64_t * obj)583 _Py_atomic_load_uint64_relaxed(const uint64_t *obj)
584 {
585     _Py_USING_STD;
586     return atomic_load_explicit((const _Atomic(uint64_t)*)obj,
587                                 memory_order_relaxed);
588 }
589 
590 static inline uintptr_t
_Py_atomic_load_uintptr_relaxed(const uintptr_t * obj)591 _Py_atomic_load_uintptr_relaxed(const uintptr_t *obj)
592 {
593     _Py_USING_STD;
594     return atomic_load_explicit((const _Atomic(uintptr_t)*)obj,
595                                 memory_order_relaxed);
596 }
597 
598 static inline unsigned int
_Py_atomic_load_uint_relaxed(const unsigned int * obj)599 _Py_atomic_load_uint_relaxed(const unsigned int *obj)
600 {
601     _Py_USING_STD;
602     return atomic_load_explicit((const _Atomic(unsigned int)*)obj,
603                                 memory_order_relaxed);
604 }
605 
606 static inline Py_ssize_t
_Py_atomic_load_ssize_relaxed(const Py_ssize_t * obj)607 _Py_atomic_load_ssize_relaxed(const Py_ssize_t *obj)
608 {
609     _Py_USING_STD;
610     return atomic_load_explicit((const _Atomic(Py_ssize_t)*)obj,
611                                 memory_order_relaxed);
612 }
613 
614 static inline void*
_Py_atomic_load_ptr_relaxed(const void * obj)615 _Py_atomic_load_ptr_relaxed(const void *obj)
616 {
617     _Py_USING_STD;
618     return atomic_load_explicit((const _Atomic(void*)*)obj,
619                                 memory_order_relaxed);
620 }
621 
622 static inline unsigned long long
_Py_atomic_load_ullong_relaxed(const unsigned long long * obj)623 _Py_atomic_load_ullong_relaxed(const unsigned long long *obj)
624 {
625     _Py_USING_STD;
626     return atomic_load_explicit((const _Atomic(unsigned long long)*)obj,
627                                 memory_order_relaxed);
628 }
629 
630 
631 // --- _Py_atomic_store ------------------------------------------------------
632 
633 static inline void
_Py_atomic_store_int(int * obj,int value)634 _Py_atomic_store_int(int *obj, int value)
635 {
636     _Py_USING_STD;
637     atomic_store((_Atomic(int)*)obj, value);
638 }
639 
640 static inline void
_Py_atomic_store_int8(int8_t * obj,int8_t value)641 _Py_atomic_store_int8(int8_t *obj, int8_t value)
642 {
643     _Py_USING_STD;
644     atomic_store((_Atomic(int8_t)*)obj, value);
645 }
646 
647 static inline void
_Py_atomic_store_int16(int16_t * obj,int16_t value)648 _Py_atomic_store_int16(int16_t *obj, int16_t value)
649 {
650     _Py_USING_STD;
651     atomic_store((_Atomic(int16_t)*)obj, value);
652 }
653 
654 static inline void
_Py_atomic_store_int32(int32_t * obj,int32_t value)655 _Py_atomic_store_int32(int32_t *obj, int32_t value)
656 {
657     _Py_USING_STD;
658     atomic_store((_Atomic(int32_t)*)obj, value);
659 }
660 
661 static inline void
_Py_atomic_store_int64(int64_t * obj,int64_t value)662 _Py_atomic_store_int64(int64_t *obj, int64_t value)
663 {
664     _Py_USING_STD;
665     atomic_store((_Atomic(int64_t)*)obj, value);
666 }
667 
668 static inline void
_Py_atomic_store_intptr(intptr_t * obj,intptr_t value)669 _Py_atomic_store_intptr(intptr_t *obj, intptr_t value)
670 {
671     _Py_USING_STD;
672     atomic_store((_Atomic(intptr_t)*)obj, value);
673 }
674 
675 static inline void
_Py_atomic_store_uint8(uint8_t * obj,uint8_t value)676 _Py_atomic_store_uint8(uint8_t *obj, uint8_t value)
677 {
678     _Py_USING_STD;
679     atomic_store((_Atomic(uint8_t)*)obj, value);
680 }
681 
682 static inline void
_Py_atomic_store_uint16(uint16_t * obj,uint16_t value)683 _Py_atomic_store_uint16(uint16_t *obj, uint16_t value)
684 {
685     _Py_USING_STD;
686     atomic_store((_Atomic(uint16_t)*)obj, value);
687 }
688 
689 static inline void
_Py_atomic_store_uint32(uint32_t * obj,uint32_t value)690 _Py_atomic_store_uint32(uint32_t *obj, uint32_t value)
691 {
692     _Py_USING_STD;
693     atomic_store((_Atomic(uint32_t)*)obj, value);
694 }
695 
696 static inline void
_Py_atomic_store_uint64(uint64_t * obj,uint64_t value)697 _Py_atomic_store_uint64(uint64_t *obj, uint64_t value)
698 {
699     _Py_USING_STD;
700     atomic_store((_Atomic(uint64_t)*)obj, value);
701 }
702 
703 static inline void
_Py_atomic_store_uintptr(uintptr_t * obj,uintptr_t value)704 _Py_atomic_store_uintptr(uintptr_t *obj, uintptr_t value)
705 {
706     _Py_USING_STD;
707     atomic_store((_Atomic(uintptr_t)*)obj, value);
708 }
709 
710 static inline void
_Py_atomic_store_uint(unsigned int * obj,unsigned int value)711 _Py_atomic_store_uint(unsigned int *obj, unsigned int value)
712 {
713     _Py_USING_STD;
714     atomic_store((_Atomic(unsigned int)*)obj, value);
715 }
716 
717 static inline void
_Py_atomic_store_ptr(void * obj,void * value)718 _Py_atomic_store_ptr(void *obj, void *value)
719 {
720     _Py_USING_STD;
721     atomic_store((_Atomic(void*)*)obj, value);
722 }
723 
724 static inline void
_Py_atomic_store_ssize(Py_ssize_t * obj,Py_ssize_t value)725 _Py_atomic_store_ssize(Py_ssize_t *obj, Py_ssize_t value)
726 {
727     _Py_USING_STD;
728     atomic_store((_Atomic(Py_ssize_t)*)obj, value);
729 }
730 
731 
732 // --- _Py_atomic_store_relaxed ----------------------------------------------
733 
734 static inline void
_Py_atomic_store_int_relaxed(int * obj,int value)735 _Py_atomic_store_int_relaxed(int *obj, int value)
736 {
737     _Py_USING_STD;
738     atomic_store_explicit((_Atomic(int)*)obj, value,
739                           memory_order_relaxed);
740 }
741 
742 static inline void
_Py_atomic_store_int8_relaxed(int8_t * obj,int8_t value)743 _Py_atomic_store_int8_relaxed(int8_t *obj, int8_t value)
744 {
745     _Py_USING_STD;
746     atomic_store_explicit((_Atomic(int8_t)*)obj, value,
747                           memory_order_relaxed);
748 }
749 
750 static inline void
_Py_atomic_store_int16_relaxed(int16_t * obj,int16_t value)751 _Py_atomic_store_int16_relaxed(int16_t *obj, int16_t value)
752 {
753     _Py_USING_STD;
754     atomic_store_explicit((_Atomic(int16_t)*)obj, value,
755                           memory_order_relaxed);
756 }
757 
758 static inline void
_Py_atomic_store_int32_relaxed(int32_t * obj,int32_t value)759 _Py_atomic_store_int32_relaxed(int32_t *obj, int32_t value)
760 {
761     _Py_USING_STD;
762     atomic_store_explicit((_Atomic(int32_t)*)obj, value,
763                           memory_order_relaxed);
764 }
765 
766 static inline void
_Py_atomic_store_int64_relaxed(int64_t * obj,int64_t value)767 _Py_atomic_store_int64_relaxed(int64_t *obj, int64_t value)
768 {
769     _Py_USING_STD;
770     atomic_store_explicit((_Atomic(int64_t)*)obj, value,
771                           memory_order_relaxed);
772 }
773 
774 static inline void
_Py_atomic_store_intptr_relaxed(intptr_t * obj,intptr_t value)775 _Py_atomic_store_intptr_relaxed(intptr_t *obj, intptr_t value)
776 {
777     _Py_USING_STD;
778     atomic_store_explicit((_Atomic(intptr_t)*)obj, value,
779                           memory_order_relaxed);
780 }
781 
782 static inline void
_Py_atomic_store_uint8_relaxed(uint8_t * obj,uint8_t value)783 _Py_atomic_store_uint8_relaxed(uint8_t *obj, uint8_t value)
784 {
785     _Py_USING_STD;
786     atomic_store_explicit((_Atomic(uint8_t)*)obj, value,
787                           memory_order_relaxed);
788 }
789 
790 static inline void
_Py_atomic_store_uint16_relaxed(uint16_t * obj,uint16_t value)791 _Py_atomic_store_uint16_relaxed(uint16_t *obj, uint16_t value)
792 {
793     _Py_USING_STD;
794     atomic_store_explicit((_Atomic(uint16_t)*)obj, value,
795                           memory_order_relaxed);
796 }
797 
798 static inline void
_Py_atomic_store_uint32_relaxed(uint32_t * obj,uint32_t value)799 _Py_atomic_store_uint32_relaxed(uint32_t *obj, uint32_t value)
800 {
801     _Py_USING_STD;
802     atomic_store_explicit((_Atomic(uint32_t)*)obj, value,
803                           memory_order_relaxed);
804 }
805 
806 static inline void
_Py_atomic_store_uint64_relaxed(uint64_t * obj,uint64_t value)807 _Py_atomic_store_uint64_relaxed(uint64_t *obj, uint64_t value)
808 {
809     _Py_USING_STD;
810     atomic_store_explicit((_Atomic(uint64_t)*)obj, value,
811                           memory_order_relaxed);
812 }
813 
814 static inline void
_Py_atomic_store_uintptr_relaxed(uintptr_t * obj,uintptr_t value)815 _Py_atomic_store_uintptr_relaxed(uintptr_t *obj, uintptr_t value)
816 {
817     _Py_USING_STD;
818     atomic_store_explicit((_Atomic(uintptr_t)*)obj, value,
819                           memory_order_relaxed);
820 }
821 
822 static inline void
_Py_atomic_store_uint_relaxed(unsigned int * obj,unsigned int value)823 _Py_atomic_store_uint_relaxed(unsigned int *obj, unsigned int value)
824 {
825     _Py_USING_STD;
826     atomic_store_explicit((_Atomic(unsigned int)*)obj, value,
827                           memory_order_relaxed);
828 }
829 
830 static inline void
_Py_atomic_store_ptr_relaxed(void * obj,void * value)831 _Py_atomic_store_ptr_relaxed(void *obj, void *value)
832 {
833     _Py_USING_STD;
834     atomic_store_explicit((_Atomic(void*)*)obj, value,
835                           memory_order_relaxed);
836 }
837 
838 static inline void
_Py_atomic_store_ssize_relaxed(Py_ssize_t * obj,Py_ssize_t value)839 _Py_atomic_store_ssize_relaxed(Py_ssize_t *obj, Py_ssize_t value)
840 {
841     _Py_USING_STD;
842     atomic_store_explicit((_Atomic(Py_ssize_t)*)obj, value,
843                           memory_order_relaxed);
844 }
845 
846 static inline void
_Py_atomic_store_ullong_relaxed(unsigned long long * obj,unsigned long long value)847 _Py_atomic_store_ullong_relaxed(unsigned long long *obj,
848                                 unsigned long long value)
849 {
850     _Py_USING_STD;
851     atomic_store_explicit((_Atomic(unsigned long long)*)obj, value,
852                           memory_order_relaxed);
853 }
854 
855 
856 // --- _Py_atomic_load_ptr_acquire / _Py_atomic_store_ptr_release ------------
857 
858 static inline void *
_Py_atomic_load_ptr_acquire(const void * obj)859 _Py_atomic_load_ptr_acquire(const void *obj)
860 {
861     _Py_USING_STD;
862     return atomic_load_explicit((const _Atomic(void*)*)obj,
863                                 memory_order_acquire);
864 }
865 
866 static inline uintptr_t
_Py_atomic_load_uintptr_acquire(const uintptr_t * obj)867 _Py_atomic_load_uintptr_acquire(const uintptr_t *obj)
868 {
869     _Py_USING_STD;
870     return atomic_load_explicit((const _Atomic(uintptr_t)*)obj,
871                                 memory_order_acquire);
872 }
873 
874 static inline void
_Py_atomic_store_ptr_release(void * obj,void * value)875 _Py_atomic_store_ptr_release(void *obj, void *value)
876 {
877     _Py_USING_STD;
878     atomic_store_explicit((_Atomic(void*)*)obj, value,
879                           memory_order_release);
880 }
881 
882 static inline void
_Py_atomic_store_uintptr_release(uintptr_t * obj,uintptr_t value)883 _Py_atomic_store_uintptr_release(uintptr_t *obj, uintptr_t value)
884 {
885     _Py_USING_STD;
886     atomic_store_explicit((_Atomic(uintptr_t)*)obj, value,
887                           memory_order_release);
888 }
889 
890 static inline void
_Py_atomic_store_int_release(int * obj,int value)891 _Py_atomic_store_int_release(int *obj, int value)
892 {
893     _Py_USING_STD;
894     atomic_store_explicit((_Atomic(int)*)obj, value,
895                           memory_order_release);
896 }
897 
898 static inline void
_Py_atomic_store_ssize_release(Py_ssize_t * obj,Py_ssize_t value)899 _Py_atomic_store_ssize_release(Py_ssize_t *obj, Py_ssize_t value)
900 {
901     _Py_USING_STD;
902     atomic_store_explicit((_Atomic(Py_ssize_t)*)obj, value,
903                           memory_order_release);
904 }
905 
906 static inline int
_Py_atomic_load_int_acquire(const int * obj)907 _Py_atomic_load_int_acquire(const int *obj)
908 {
909     _Py_USING_STD;
910     return atomic_load_explicit((const _Atomic(int)*)obj,
911                                 memory_order_acquire);
912 }
913 
914 static inline void
_Py_atomic_store_uint32_release(uint32_t * obj,uint32_t value)915 _Py_atomic_store_uint32_release(uint32_t *obj, uint32_t value)
916 {
917     _Py_USING_STD;
918     atomic_store_explicit((_Atomic(uint32_t)*)obj, value,
919                           memory_order_release);
920 }
921 
922 static inline void
_Py_atomic_store_uint64_release(uint64_t * obj,uint64_t value)923 _Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value)
924 {
925     _Py_USING_STD;
926     atomic_store_explicit((_Atomic(uint64_t)*)obj, value,
927                           memory_order_release);
928 }
929 
930 static inline uint64_t
_Py_atomic_load_uint64_acquire(const uint64_t * obj)931 _Py_atomic_load_uint64_acquire(const uint64_t *obj)
932 {
933     _Py_USING_STD;
934     return atomic_load_explicit((const _Atomic(uint64_t)*)obj,
935                                 memory_order_acquire);
936 }
937 
938 static inline uint32_t
_Py_atomic_load_uint32_acquire(const uint32_t * obj)939 _Py_atomic_load_uint32_acquire(const uint32_t *obj)
940 {
941     _Py_USING_STD;
942     return atomic_load_explicit((const _Atomic(uint32_t)*)obj,
943                                 memory_order_acquire);
944 }
945 
946 static inline Py_ssize_t
_Py_atomic_load_ssize_acquire(const Py_ssize_t * obj)947 _Py_atomic_load_ssize_acquire(const Py_ssize_t *obj)
948 {
949     _Py_USING_STD;
950     return atomic_load_explicit((const _Atomic(Py_ssize_t)*)obj,
951                                 memory_order_acquire);
952 }
953 
954 
955 // --- _Py_atomic_fence ------------------------------------------------------
956 
957  static inline void
_Py_atomic_fence_seq_cst(void)958 _Py_atomic_fence_seq_cst(void)
959 {
960     _Py_USING_STD;
961     atomic_thread_fence(memory_order_seq_cst);
962 }
963 
964  static inline void
_Py_atomic_fence_acquire(void)965 _Py_atomic_fence_acquire(void)
966 {
967     _Py_USING_STD;
968     atomic_thread_fence(memory_order_acquire);
969 }
970 
971  static inline void
_Py_atomic_fence_release(void)972 _Py_atomic_fence_release(void)
973 {
974     _Py_USING_STD;
975     atomic_thread_fence(memory_order_release);
976 }
977