11#ifndef Py_LIMITED_API
22#ifndef Py_ATOMIC_H
33#define Py_ATOMIC_H
4- /* XXX: When compilers start offering a stdatomic.h with lock-free
5- atomic_int and atomic_address types, include that here and rewrite
6- the atomic operations in terms of it. */
74
85#include "dynamic_annotations.h"
96
7+ #include "pyconfig.h"
8+
9+ #if defined(HAVE_STD_ATOMIC )
10+ #include <stdatomic.h>
11+ #endif
12+
1013#ifdef __cplusplus
1114extern "C" {
1215#endif
@@ -20,6 +23,76 @@ extern "C" {
2023 * Beware, the implementations here are deep magic.
2124 */
2225
26+ #if defined(HAVE_STD_ATOMIC )
27+
28+ typedef enum _Py_memory_order {
29+ _Py_memory_order_relaxed = memory_order_relaxed ,
30+ _Py_memory_order_acquire = memory_order_acquire ,
31+ _Py_memory_order_release = memory_order_release ,
32+ _Py_memory_order_acq_rel = memory_order_acq_rel ,
33+ _Py_memory_order_seq_cst = memory_order_seq_cst
34+ } _Py_memory_order ;
35+
36+ typedef struct _Py_atomic_address {
37+ _Atomic void * _value ;
38+ } _Py_atomic_address ;
39+
40+ typedef struct _Py_atomic_int {
41+ atomic_int _value ;
42+ } _Py_atomic_int ;
43+
44+ #define _Py_atomic_signal_fence (/*memory_order*/ ORDER ) \
45+ atomic_signal_fence(ORDER)
46+
47+ #define _Py_atomic_thread_fence (/*memory_order*/ ORDER ) \
48+ atomic_thread_fence(ORDER)
49+
50+ #define _Py_atomic_store_explicit (ATOMIC_VAL , NEW_VAL , ORDER ) \
51+ atomic_store_explicit(&(ATOMIC_VAL)->_value, NEW_VAL, ORDER)
52+
53+ #define _Py_atomic_load_explicit (ATOMIC_VAL , ORDER ) \
54+ atomic_load_explicit(&(ATOMIC_VAL)->_value, ORDER)
55+
56+ /* Use builtin atomic operations in GCC >= 4.7 */
57+ #elif defined(HAVE_BUILTIN_ATOMIC )
58+
59+ typedef enum _Py_memory_order {
60+ _Py_memory_order_relaxed = __ATOMIC_RELAXED ,
61+ _Py_memory_order_acquire = __ATOMIC_ACQUIRE ,
62+ _Py_memory_order_release = __ATOMIC_RELEASE ,
63+ _Py_memory_order_acq_rel = __ATOMIC_ACQ_REL ,
64+ _Py_memory_order_seq_cst = __ATOMIC_SEQ_CST
65+ } _Py_memory_order ;
66+
67+ typedef struct _Py_atomic_address {
68+ void * _value ;
69+ } _Py_atomic_address ;
70+
71+ typedef struct _Py_atomic_int {
72+ int _value ;
73+ } _Py_atomic_int ;
74+
75+ #define _Py_atomic_signal_fence (/*memory_order*/ ORDER ) \
76+ __atomic_signal_fence(ORDER)
77+
78+ #define _Py_atomic_thread_fence (/*memory_order*/ ORDER ) \
79+ __atomic_thread_fence(ORDER)
80+
81+ #define _Py_atomic_store_explicit (ATOMIC_VAL , NEW_VAL , ORDER ) \
82+ (assert((ORDER) == __ATOMIC_RELAXED \
83+ || (ORDER) == __ATOMIC_SEQ_CST \
84+ || (ORDER) == __ATOMIC_RELEASE), \
85+ __atomic_store_n(&(ATOMIC_VAL)->_value, NEW_VAL, ORDER))
86+
87+ #define _Py_atomic_load_explicit (ATOMIC_VAL , ORDER ) \
88+ (assert((ORDER) == __ATOMIC_RELAXED \
89+ || (ORDER) == __ATOMIC_SEQ_CST \
90+ || (ORDER) == __ATOMIC_ACQUIRE \
91+ || (ORDER) == __ATOMIC_CONSUME), \
92+ __atomic_load_n(&(ATOMIC_VAL)->_value, ORDER))
93+
94+ #else
95+
2396typedef enum _Py_memory_order {
2497 _Py_memory_order_relaxed ,
2598 _Py_memory_order_acquire ,
@@ -162,6 +235,7 @@ _Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order)
162235 ((ATOMIC_VAL)->_value)
163236
164237#endif /* !gcc x86 */
238+ #endif
165239
166240/* Standardized shortcuts. */
167241#define _Py_atomic_store (ATOMIC_VAL , NEW_VAL ) \
0 commit comments