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