17db96d56Sopenharmony_ci#ifndef Py_ATOMIC_H 27db96d56Sopenharmony_ci#define Py_ATOMIC_H 37db96d56Sopenharmony_ci#ifdef __cplusplus 47db96d56Sopenharmony_ciextern "C" { 57db96d56Sopenharmony_ci#endif 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE 87db96d56Sopenharmony_ci# error "this header requires Py_BUILD_CORE define" 97db96d56Sopenharmony_ci#endif 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci#include "dynamic_annotations.h" /* _Py_ANNOTATE_MEMORY_ORDER */ 127db96d56Sopenharmony_ci#include "pyconfig.h" 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci#ifdef HAVE_STD_ATOMIC 157db96d56Sopenharmony_ci# include <stdatomic.h> 167db96d56Sopenharmony_ci#endif 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci#if defined(_MSC_VER) 207db96d56Sopenharmony_ci#include <intrin.h> 217db96d56Sopenharmony_ci#if defined(_M_IX86) || defined(_M_X64) 227db96d56Sopenharmony_ci# include <immintrin.h> 237db96d56Sopenharmony_ci#endif 247db96d56Sopenharmony_ci#endif 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_ci/* This is modeled after the atomics interface from C1x, according to 277db96d56Sopenharmony_ci * the draft at 287db96d56Sopenharmony_ci * http://www.open-std.org/JTC1/SC22/wg14/www/docs/n1425.pdf. 297db96d56Sopenharmony_ci * Operations and types are named the same except with a _Py_ prefix 307db96d56Sopenharmony_ci * and have the same semantics. 317db96d56Sopenharmony_ci * 327db96d56Sopenharmony_ci * Beware, the implementations here are deep magic. 337db96d56Sopenharmony_ci */ 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_ci#if defined(HAVE_STD_ATOMIC) 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_citypedef enum _Py_memory_order { 387db96d56Sopenharmony_ci _Py_memory_order_relaxed = memory_order_relaxed, 397db96d56Sopenharmony_ci _Py_memory_order_acquire = memory_order_acquire, 407db96d56Sopenharmony_ci _Py_memory_order_release = memory_order_release, 417db96d56Sopenharmony_ci _Py_memory_order_acq_rel = memory_order_acq_rel, 427db96d56Sopenharmony_ci _Py_memory_order_seq_cst = memory_order_seq_cst 437db96d56Sopenharmony_ci} _Py_memory_order; 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_citypedef struct _Py_atomic_address { 467db96d56Sopenharmony_ci atomic_uintptr_t _value; 477db96d56Sopenharmony_ci} _Py_atomic_address; 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_citypedef struct _Py_atomic_int { 507db96d56Sopenharmony_ci atomic_int _value; 517db96d56Sopenharmony_ci} _Py_atomic_int; 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ 547db96d56Sopenharmony_ci atomic_signal_fence(ORDER) 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ci#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ 577db96d56Sopenharmony_ci atomic_thread_fence(ORDER) 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ 607db96d56Sopenharmony_ci atomic_store_explicit(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER) 617db96d56Sopenharmony_ci 627db96d56Sopenharmony_ci#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ 637db96d56Sopenharmony_ci atomic_load_explicit(&((ATOMIC_VAL)->_value), ORDER) 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci// Use builtin atomic operations in GCC >= 4.7 and clang 667db96d56Sopenharmony_ci#elif defined(HAVE_BUILTIN_ATOMIC) 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_citypedef enum _Py_memory_order { 697db96d56Sopenharmony_ci _Py_memory_order_relaxed = __ATOMIC_RELAXED, 707db96d56Sopenharmony_ci _Py_memory_order_acquire = __ATOMIC_ACQUIRE, 717db96d56Sopenharmony_ci _Py_memory_order_release = __ATOMIC_RELEASE, 727db96d56Sopenharmony_ci _Py_memory_order_acq_rel = __ATOMIC_ACQ_REL, 737db96d56Sopenharmony_ci _Py_memory_order_seq_cst = __ATOMIC_SEQ_CST 747db96d56Sopenharmony_ci} _Py_memory_order; 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_citypedef struct _Py_atomic_address { 777db96d56Sopenharmony_ci uintptr_t _value; 787db96d56Sopenharmony_ci} _Py_atomic_address; 797db96d56Sopenharmony_ci 807db96d56Sopenharmony_citypedef struct _Py_atomic_int { 817db96d56Sopenharmony_ci int _value; 827db96d56Sopenharmony_ci} _Py_atomic_int; 837db96d56Sopenharmony_ci 847db96d56Sopenharmony_ci#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) \ 857db96d56Sopenharmony_ci __atomic_signal_fence(ORDER) 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ci#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) \ 887db96d56Sopenharmony_ci __atomic_thread_fence(ORDER) 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ 917db96d56Sopenharmony_ci (assert((ORDER) == __ATOMIC_RELAXED \ 927db96d56Sopenharmony_ci || (ORDER) == __ATOMIC_SEQ_CST \ 937db96d56Sopenharmony_ci || (ORDER) == __ATOMIC_RELEASE), \ 947db96d56Sopenharmony_ci __atomic_store_n(&((ATOMIC_VAL)->_value), NEW_VAL, ORDER)) 957db96d56Sopenharmony_ci 967db96d56Sopenharmony_ci#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ 977db96d56Sopenharmony_ci (assert((ORDER) == __ATOMIC_RELAXED \ 987db96d56Sopenharmony_ci || (ORDER) == __ATOMIC_SEQ_CST \ 997db96d56Sopenharmony_ci || (ORDER) == __ATOMIC_ACQUIRE \ 1007db96d56Sopenharmony_ci || (ORDER) == __ATOMIC_CONSUME), \ 1017db96d56Sopenharmony_ci __atomic_load_n(&((ATOMIC_VAL)->_value), ORDER)) 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci/* Only support GCC (for expression statements) and x86 (for simple 1047db96d56Sopenharmony_ci * atomic semantics) and MSVC x86/x64/ARM */ 1057db96d56Sopenharmony_ci#elif defined(__GNUC__) && (defined(__i386__) || defined(__amd64)) 1067db96d56Sopenharmony_citypedef enum _Py_memory_order { 1077db96d56Sopenharmony_ci _Py_memory_order_relaxed, 1087db96d56Sopenharmony_ci _Py_memory_order_acquire, 1097db96d56Sopenharmony_ci _Py_memory_order_release, 1107db96d56Sopenharmony_ci _Py_memory_order_acq_rel, 1117db96d56Sopenharmony_ci _Py_memory_order_seq_cst 1127db96d56Sopenharmony_ci} _Py_memory_order; 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_citypedef struct _Py_atomic_address { 1157db96d56Sopenharmony_ci uintptr_t _value; 1167db96d56Sopenharmony_ci} _Py_atomic_address; 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_citypedef struct _Py_atomic_int { 1197db96d56Sopenharmony_ci int _value; 1207db96d56Sopenharmony_ci} _Py_atomic_int; 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_cistatic __inline__ void 1247db96d56Sopenharmony_ci_Py_atomic_signal_fence(_Py_memory_order order) 1257db96d56Sopenharmony_ci{ 1267db96d56Sopenharmony_ci if (order != _Py_memory_order_relaxed) 1277db96d56Sopenharmony_ci __asm__ volatile("":::"memory"); 1287db96d56Sopenharmony_ci} 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_cistatic __inline__ void 1317db96d56Sopenharmony_ci_Py_atomic_thread_fence(_Py_memory_order order) 1327db96d56Sopenharmony_ci{ 1337db96d56Sopenharmony_ci if (order != _Py_memory_order_relaxed) 1347db96d56Sopenharmony_ci __asm__ volatile("mfence":::"memory"); 1357db96d56Sopenharmony_ci} 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci/* Tell the race checker about this operation's effects. */ 1387db96d56Sopenharmony_cistatic __inline__ void 1397db96d56Sopenharmony_ci_Py_ANNOTATE_MEMORY_ORDER(const volatile void *address, _Py_memory_order order) 1407db96d56Sopenharmony_ci{ 1417db96d56Sopenharmony_ci (void)address; /* shut up -Wunused-parameter */ 1427db96d56Sopenharmony_ci switch(order) { 1437db96d56Sopenharmony_ci case _Py_memory_order_release: 1447db96d56Sopenharmony_ci case _Py_memory_order_acq_rel: 1457db96d56Sopenharmony_ci case _Py_memory_order_seq_cst: 1467db96d56Sopenharmony_ci _Py_ANNOTATE_HAPPENS_BEFORE(address); 1477db96d56Sopenharmony_ci break; 1487db96d56Sopenharmony_ci case _Py_memory_order_relaxed: 1497db96d56Sopenharmony_ci case _Py_memory_order_acquire: 1507db96d56Sopenharmony_ci break; 1517db96d56Sopenharmony_ci } 1527db96d56Sopenharmony_ci switch(order) { 1537db96d56Sopenharmony_ci case _Py_memory_order_acquire: 1547db96d56Sopenharmony_ci case _Py_memory_order_acq_rel: 1557db96d56Sopenharmony_ci case _Py_memory_order_seq_cst: 1567db96d56Sopenharmony_ci _Py_ANNOTATE_HAPPENS_AFTER(address); 1577db96d56Sopenharmony_ci break; 1587db96d56Sopenharmony_ci case _Py_memory_order_relaxed: 1597db96d56Sopenharmony_ci case _Py_memory_order_release: 1607db96d56Sopenharmony_ci break; 1617db96d56Sopenharmony_ci } 1627db96d56Sopenharmony_ci} 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ 1657db96d56Sopenharmony_ci __extension__ ({ \ 1667db96d56Sopenharmony_ci __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \ 1677db96d56Sopenharmony_ci __typeof__(atomic_val->_value) new_val = NEW_VAL;\ 1687db96d56Sopenharmony_ci volatile __typeof__(new_val) *volatile_data = &atomic_val->_value; \ 1697db96d56Sopenharmony_ci _Py_memory_order order = ORDER; \ 1707db96d56Sopenharmony_ci _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \ 1717db96d56Sopenharmony_ci \ 1727db96d56Sopenharmony_ci /* Perform the operation. */ \ 1737db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_WRITES_BEGIN(); \ 1747db96d56Sopenharmony_ci switch(order) { \ 1757db96d56Sopenharmony_ci case _Py_memory_order_release: \ 1767db96d56Sopenharmony_ci _Py_atomic_signal_fence(_Py_memory_order_release); \ 1777db96d56Sopenharmony_ci /* fallthrough */ \ 1787db96d56Sopenharmony_ci case _Py_memory_order_relaxed: \ 1797db96d56Sopenharmony_ci *volatile_data = new_val; \ 1807db96d56Sopenharmony_ci break; \ 1817db96d56Sopenharmony_ci \ 1827db96d56Sopenharmony_ci case _Py_memory_order_acquire: \ 1837db96d56Sopenharmony_ci case _Py_memory_order_acq_rel: \ 1847db96d56Sopenharmony_ci case _Py_memory_order_seq_cst: \ 1857db96d56Sopenharmony_ci __asm__ volatile("xchg %0, %1" \ 1867db96d56Sopenharmony_ci : "+r"(new_val) \ 1877db96d56Sopenharmony_ci : "m"(atomic_val->_value) \ 1887db96d56Sopenharmony_ci : "memory"); \ 1897db96d56Sopenharmony_ci break; \ 1907db96d56Sopenharmony_ci } \ 1917db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_WRITES_END(); \ 1927db96d56Sopenharmony_ci }) 1937db96d56Sopenharmony_ci 1947db96d56Sopenharmony_ci#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ 1957db96d56Sopenharmony_ci __extension__ ({ \ 1967db96d56Sopenharmony_ci __typeof__(ATOMIC_VAL) atomic_val = ATOMIC_VAL; \ 1977db96d56Sopenharmony_ci __typeof__(atomic_val->_value) result; \ 1987db96d56Sopenharmony_ci volatile __typeof__(result) *volatile_data = &atomic_val->_value; \ 1997db96d56Sopenharmony_ci _Py_memory_order order = ORDER; \ 2007db96d56Sopenharmony_ci _Py_ANNOTATE_MEMORY_ORDER(atomic_val, order); \ 2017db96d56Sopenharmony_ci \ 2027db96d56Sopenharmony_ci /* Perform the operation. */ \ 2037db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_READS_BEGIN(); \ 2047db96d56Sopenharmony_ci switch(order) { \ 2057db96d56Sopenharmony_ci case _Py_memory_order_release: \ 2067db96d56Sopenharmony_ci case _Py_memory_order_acq_rel: \ 2077db96d56Sopenharmony_ci case _Py_memory_order_seq_cst: \ 2087db96d56Sopenharmony_ci /* Loads on x86 are not releases by default, so need a */ \ 2097db96d56Sopenharmony_ci /* thread fence. */ \ 2107db96d56Sopenharmony_ci _Py_atomic_thread_fence(_Py_memory_order_release); \ 2117db96d56Sopenharmony_ci break; \ 2127db96d56Sopenharmony_ci default: \ 2137db96d56Sopenharmony_ci /* No fence */ \ 2147db96d56Sopenharmony_ci break; \ 2157db96d56Sopenharmony_ci } \ 2167db96d56Sopenharmony_ci result = *volatile_data; \ 2177db96d56Sopenharmony_ci switch(order) { \ 2187db96d56Sopenharmony_ci case _Py_memory_order_acquire: \ 2197db96d56Sopenharmony_ci case _Py_memory_order_acq_rel: \ 2207db96d56Sopenharmony_ci case _Py_memory_order_seq_cst: \ 2217db96d56Sopenharmony_ci /* Loads on x86 are automatically acquire operations so */ \ 2227db96d56Sopenharmony_ci /* can get by with just a compiler fence. */ \ 2237db96d56Sopenharmony_ci _Py_atomic_signal_fence(_Py_memory_order_acquire); \ 2247db96d56Sopenharmony_ci break; \ 2257db96d56Sopenharmony_ci default: \ 2267db96d56Sopenharmony_ci /* No fence */ \ 2277db96d56Sopenharmony_ci break; \ 2287db96d56Sopenharmony_ci } \ 2297db96d56Sopenharmony_ci _Py_ANNOTATE_IGNORE_READS_END(); \ 2307db96d56Sopenharmony_ci result; \ 2317db96d56Sopenharmony_ci }) 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci#elif defined(_MSC_VER) 2347db96d56Sopenharmony_ci/* _Interlocked* functions provide a full memory barrier and are therefore 2357db96d56Sopenharmony_ci enough for acq_rel and seq_cst. If the HLE variants aren't available 2367db96d56Sopenharmony_ci in hardware they will fall back to a full memory barrier as well. 2377db96d56Sopenharmony_ci 2387db96d56Sopenharmony_ci This might affect performance but likely only in some very specific and 2397db96d56Sopenharmony_ci hard to measure scenario. 2407db96d56Sopenharmony_ci*/ 2417db96d56Sopenharmony_ci#if defined(_M_IX86) || defined(_M_X64) 2427db96d56Sopenharmony_citypedef enum _Py_memory_order { 2437db96d56Sopenharmony_ci _Py_memory_order_relaxed, 2447db96d56Sopenharmony_ci _Py_memory_order_acquire, 2457db96d56Sopenharmony_ci _Py_memory_order_release, 2467db96d56Sopenharmony_ci _Py_memory_order_acq_rel, 2477db96d56Sopenharmony_ci _Py_memory_order_seq_cst 2487db96d56Sopenharmony_ci} _Py_memory_order; 2497db96d56Sopenharmony_ci 2507db96d56Sopenharmony_citypedef struct _Py_atomic_address { 2517db96d56Sopenharmony_ci volatile uintptr_t _value; 2527db96d56Sopenharmony_ci} _Py_atomic_address; 2537db96d56Sopenharmony_ci 2547db96d56Sopenharmony_citypedef struct _Py_atomic_int { 2557db96d56Sopenharmony_ci volatile int _value; 2567db96d56Sopenharmony_ci} _Py_atomic_int; 2577db96d56Sopenharmony_ci 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci#if defined(_M_X64) 2607db96d56Sopenharmony_ci#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ 2617db96d56Sopenharmony_ci switch (ORDER) { \ 2627db96d56Sopenharmony_ci case _Py_memory_order_acquire: \ 2637db96d56Sopenharmony_ci _InterlockedExchange64_HLEAcquire((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ 2647db96d56Sopenharmony_ci break; \ 2657db96d56Sopenharmony_ci case _Py_memory_order_release: \ 2667db96d56Sopenharmony_ci _InterlockedExchange64_HLERelease((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ 2677db96d56Sopenharmony_ci break; \ 2687db96d56Sopenharmony_ci default: \ 2697db96d56Sopenharmony_ci _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)(NEW_VAL)); \ 2707db96d56Sopenharmony_ci break; \ 2717db96d56Sopenharmony_ci } 2727db96d56Sopenharmony_ci#else 2737db96d56Sopenharmony_ci#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0); 2747db96d56Sopenharmony_ci#endif 2757db96d56Sopenharmony_ci 2767db96d56Sopenharmony_ci#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ 2777db96d56Sopenharmony_ci switch (ORDER) { \ 2787db96d56Sopenharmony_ci case _Py_memory_order_acquire: \ 2797db96d56Sopenharmony_ci _InterlockedExchange_HLEAcquire((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ 2807db96d56Sopenharmony_ci break; \ 2817db96d56Sopenharmony_ci case _Py_memory_order_release: \ 2827db96d56Sopenharmony_ci _InterlockedExchange_HLERelease((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ 2837db96d56Sopenharmony_ci break; \ 2847db96d56Sopenharmony_ci default: \ 2857db96d56Sopenharmony_ci _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)(NEW_VAL)); \ 2867db96d56Sopenharmony_ci break; \ 2877db96d56Sopenharmony_ci } 2887db96d56Sopenharmony_ci 2897db96d56Sopenharmony_ci#if defined(_M_X64) 2907db96d56Sopenharmony_ci/* This has to be an intptr_t for now. 2917db96d56Sopenharmony_ci gil_created() uses -1 as a sentinel value, if this returns 2927db96d56Sopenharmony_ci a uintptr_t it will do an unsigned compare and crash 2937db96d56Sopenharmony_ci*/ 2947db96d56Sopenharmony_ciinline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) { 2957db96d56Sopenharmony_ci __int64 old; 2967db96d56Sopenharmony_ci switch (order) { 2977db96d56Sopenharmony_ci case _Py_memory_order_acquire: 2987db96d56Sopenharmony_ci { 2997db96d56Sopenharmony_ci do { 3007db96d56Sopenharmony_ci old = *value; 3017db96d56Sopenharmony_ci } while(_InterlockedCompareExchange64_HLEAcquire((volatile __int64*)value, old, old) != old); 3027db96d56Sopenharmony_ci break; 3037db96d56Sopenharmony_ci } 3047db96d56Sopenharmony_ci case _Py_memory_order_release: 3057db96d56Sopenharmony_ci { 3067db96d56Sopenharmony_ci do { 3077db96d56Sopenharmony_ci old = *value; 3087db96d56Sopenharmony_ci } while(_InterlockedCompareExchange64_HLERelease((volatile __int64*)value, old, old) != old); 3097db96d56Sopenharmony_ci break; 3107db96d56Sopenharmony_ci } 3117db96d56Sopenharmony_ci case _Py_memory_order_relaxed: 3127db96d56Sopenharmony_ci old = *value; 3137db96d56Sopenharmony_ci break; 3147db96d56Sopenharmony_ci default: 3157db96d56Sopenharmony_ci { 3167db96d56Sopenharmony_ci do { 3177db96d56Sopenharmony_ci old = *value; 3187db96d56Sopenharmony_ci } while(_InterlockedCompareExchange64((volatile __int64*)value, old, old) != old); 3197db96d56Sopenharmony_ci break; 3207db96d56Sopenharmony_ci } 3217db96d56Sopenharmony_ci } 3227db96d56Sopenharmony_ci return old; 3237db96d56Sopenharmony_ci} 3247db96d56Sopenharmony_ci 3257db96d56Sopenharmony_ci#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \ 3267db96d56Sopenharmony_ci _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER)) 3277db96d56Sopenharmony_ci 3287db96d56Sopenharmony_ci#else 3297db96d56Sopenharmony_ci#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value) 3307db96d56Sopenharmony_ci#endif 3317db96d56Sopenharmony_ci 3327db96d56Sopenharmony_ciinline int _Py_atomic_load_32bit_impl(volatile int* value, int order) { 3337db96d56Sopenharmony_ci long old; 3347db96d56Sopenharmony_ci switch (order) { 3357db96d56Sopenharmony_ci case _Py_memory_order_acquire: 3367db96d56Sopenharmony_ci { 3377db96d56Sopenharmony_ci do { 3387db96d56Sopenharmony_ci old = *value; 3397db96d56Sopenharmony_ci } while(_InterlockedCompareExchange_HLEAcquire((volatile long*)value, old, old) != old); 3407db96d56Sopenharmony_ci break; 3417db96d56Sopenharmony_ci } 3427db96d56Sopenharmony_ci case _Py_memory_order_release: 3437db96d56Sopenharmony_ci { 3447db96d56Sopenharmony_ci do { 3457db96d56Sopenharmony_ci old = *value; 3467db96d56Sopenharmony_ci } while(_InterlockedCompareExchange_HLERelease((volatile long*)value, old, old) != old); 3477db96d56Sopenharmony_ci break; 3487db96d56Sopenharmony_ci } 3497db96d56Sopenharmony_ci case _Py_memory_order_relaxed: 3507db96d56Sopenharmony_ci old = *value; 3517db96d56Sopenharmony_ci break; 3527db96d56Sopenharmony_ci default: 3537db96d56Sopenharmony_ci { 3547db96d56Sopenharmony_ci do { 3557db96d56Sopenharmony_ci old = *value; 3567db96d56Sopenharmony_ci } while(_InterlockedCompareExchange((volatile long*)value, old, old) != old); 3577db96d56Sopenharmony_ci break; 3587db96d56Sopenharmony_ci } 3597db96d56Sopenharmony_ci } 3607db96d56Sopenharmony_ci return old; 3617db96d56Sopenharmony_ci} 3627db96d56Sopenharmony_ci 3637db96d56Sopenharmony_ci#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \ 3647db96d56Sopenharmony_ci _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER)) 3657db96d56Sopenharmony_ci 3667db96d56Sopenharmony_ci#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ 3677db96d56Sopenharmony_ci if (sizeof((ATOMIC_VAL)->_value) == 8) { \ 3687db96d56Sopenharmony_ci _Py_atomic_store_64bit((ATOMIC_VAL), NEW_VAL, ORDER) } else { \ 3697db96d56Sopenharmony_ci _Py_atomic_store_32bit((ATOMIC_VAL), NEW_VAL, ORDER) } 3707db96d56Sopenharmony_ci 3717db96d56Sopenharmony_ci#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ 3727db96d56Sopenharmony_ci ( \ 3737db96d56Sopenharmony_ci sizeof((ATOMIC_VAL)->_value) == 8 ? \ 3747db96d56Sopenharmony_ci _Py_atomic_load_64bit((ATOMIC_VAL), ORDER) : \ 3757db96d56Sopenharmony_ci _Py_atomic_load_32bit((ATOMIC_VAL), ORDER) \ 3767db96d56Sopenharmony_ci ) 3777db96d56Sopenharmony_ci#elif defined(_M_ARM) || defined(_M_ARM64) 3787db96d56Sopenharmony_citypedef enum _Py_memory_order { 3797db96d56Sopenharmony_ci _Py_memory_order_relaxed, 3807db96d56Sopenharmony_ci _Py_memory_order_acquire, 3817db96d56Sopenharmony_ci _Py_memory_order_release, 3827db96d56Sopenharmony_ci _Py_memory_order_acq_rel, 3837db96d56Sopenharmony_ci _Py_memory_order_seq_cst 3847db96d56Sopenharmony_ci} _Py_memory_order; 3857db96d56Sopenharmony_ci 3867db96d56Sopenharmony_citypedef struct _Py_atomic_address { 3877db96d56Sopenharmony_ci volatile uintptr_t _value; 3887db96d56Sopenharmony_ci} _Py_atomic_address; 3897db96d56Sopenharmony_ci 3907db96d56Sopenharmony_citypedef struct _Py_atomic_int { 3917db96d56Sopenharmony_ci volatile int _value; 3927db96d56Sopenharmony_ci} _Py_atomic_int; 3937db96d56Sopenharmony_ci 3947db96d56Sopenharmony_ci 3957db96d56Sopenharmony_ci#if defined(_M_ARM64) 3967db96d56Sopenharmony_ci#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) \ 3977db96d56Sopenharmony_ci switch (ORDER) { \ 3987db96d56Sopenharmony_ci case _Py_memory_order_acquire: \ 3997db96d56Sopenharmony_ci _InterlockedExchange64_acq((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ 4007db96d56Sopenharmony_ci break; \ 4017db96d56Sopenharmony_ci case _Py_memory_order_release: \ 4027db96d56Sopenharmony_ci _InterlockedExchange64_rel((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ 4037db96d56Sopenharmony_ci break; \ 4047db96d56Sopenharmony_ci default: \ 4057db96d56Sopenharmony_ci _InterlockedExchange64((__int64 volatile*)&((ATOMIC_VAL)->_value), (__int64)NEW_VAL); \ 4067db96d56Sopenharmony_ci break; \ 4077db96d56Sopenharmony_ci } 4087db96d56Sopenharmony_ci#else 4097db96d56Sopenharmony_ci#define _Py_atomic_store_64bit(ATOMIC_VAL, NEW_VAL, ORDER) ((void)0); 4107db96d56Sopenharmony_ci#endif 4117db96d56Sopenharmony_ci 4127db96d56Sopenharmony_ci#define _Py_atomic_store_32bit(ATOMIC_VAL, NEW_VAL, ORDER) \ 4137db96d56Sopenharmony_ci switch (ORDER) { \ 4147db96d56Sopenharmony_ci case _Py_memory_order_acquire: \ 4157db96d56Sopenharmony_ci _InterlockedExchange_acq((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ 4167db96d56Sopenharmony_ci break; \ 4177db96d56Sopenharmony_ci case _Py_memory_order_release: \ 4187db96d56Sopenharmony_ci _InterlockedExchange_rel((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ 4197db96d56Sopenharmony_ci break; \ 4207db96d56Sopenharmony_ci default: \ 4217db96d56Sopenharmony_ci _InterlockedExchange((volatile long*)&((ATOMIC_VAL)->_value), (int)NEW_VAL); \ 4227db96d56Sopenharmony_ci break; \ 4237db96d56Sopenharmony_ci } 4247db96d56Sopenharmony_ci 4257db96d56Sopenharmony_ci#if defined(_M_ARM64) 4267db96d56Sopenharmony_ci/* This has to be an intptr_t for now. 4277db96d56Sopenharmony_ci gil_created() uses -1 as a sentinel value, if this returns 4287db96d56Sopenharmony_ci a uintptr_t it will do an unsigned compare and crash 4297db96d56Sopenharmony_ci*/ 4307db96d56Sopenharmony_ciinline intptr_t _Py_atomic_load_64bit_impl(volatile uintptr_t* value, int order) { 4317db96d56Sopenharmony_ci uintptr_t old; 4327db96d56Sopenharmony_ci switch (order) { 4337db96d56Sopenharmony_ci case _Py_memory_order_acquire: 4347db96d56Sopenharmony_ci { 4357db96d56Sopenharmony_ci do { 4367db96d56Sopenharmony_ci old = *value; 4377db96d56Sopenharmony_ci } while(_InterlockedCompareExchange64_acq(value, old, old) != old); 4387db96d56Sopenharmony_ci break; 4397db96d56Sopenharmony_ci } 4407db96d56Sopenharmony_ci case _Py_memory_order_release: 4417db96d56Sopenharmony_ci { 4427db96d56Sopenharmony_ci do { 4437db96d56Sopenharmony_ci old = *value; 4447db96d56Sopenharmony_ci } while(_InterlockedCompareExchange64_rel(value, old, old) != old); 4457db96d56Sopenharmony_ci break; 4467db96d56Sopenharmony_ci } 4477db96d56Sopenharmony_ci case _Py_memory_order_relaxed: 4487db96d56Sopenharmony_ci old = *value; 4497db96d56Sopenharmony_ci break; 4507db96d56Sopenharmony_ci default: 4517db96d56Sopenharmony_ci { 4527db96d56Sopenharmony_ci do { 4537db96d56Sopenharmony_ci old = *value; 4547db96d56Sopenharmony_ci } while(_InterlockedCompareExchange64(value, old, old) != old); 4557db96d56Sopenharmony_ci break; 4567db96d56Sopenharmony_ci } 4577db96d56Sopenharmony_ci } 4587db96d56Sopenharmony_ci return old; 4597db96d56Sopenharmony_ci} 4607db96d56Sopenharmony_ci 4617db96d56Sopenharmony_ci#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) \ 4627db96d56Sopenharmony_ci _Py_atomic_load_64bit_impl((volatile uintptr_t*)&((ATOMIC_VAL)->_value), (ORDER)) 4637db96d56Sopenharmony_ci 4647db96d56Sopenharmony_ci#else 4657db96d56Sopenharmony_ci#define _Py_atomic_load_64bit(ATOMIC_VAL, ORDER) ((ATOMIC_VAL)->_value) 4667db96d56Sopenharmony_ci#endif 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ciinline int _Py_atomic_load_32bit_impl(volatile int* value, int order) { 4697db96d56Sopenharmony_ci int old; 4707db96d56Sopenharmony_ci switch (order) { 4717db96d56Sopenharmony_ci case _Py_memory_order_acquire: 4727db96d56Sopenharmony_ci { 4737db96d56Sopenharmony_ci do { 4747db96d56Sopenharmony_ci old = *value; 4757db96d56Sopenharmony_ci } while(_InterlockedCompareExchange_acq(value, old, old) != old); 4767db96d56Sopenharmony_ci break; 4777db96d56Sopenharmony_ci } 4787db96d56Sopenharmony_ci case _Py_memory_order_release: 4797db96d56Sopenharmony_ci { 4807db96d56Sopenharmony_ci do { 4817db96d56Sopenharmony_ci old = *value; 4827db96d56Sopenharmony_ci } while(_InterlockedCompareExchange_rel(value, old, old) != old); 4837db96d56Sopenharmony_ci break; 4847db96d56Sopenharmony_ci } 4857db96d56Sopenharmony_ci case _Py_memory_order_relaxed: 4867db96d56Sopenharmony_ci old = *value; 4877db96d56Sopenharmony_ci break; 4887db96d56Sopenharmony_ci default: 4897db96d56Sopenharmony_ci { 4907db96d56Sopenharmony_ci do { 4917db96d56Sopenharmony_ci old = *value; 4927db96d56Sopenharmony_ci } while(_InterlockedCompareExchange(value, old, old) != old); 4937db96d56Sopenharmony_ci break; 4947db96d56Sopenharmony_ci } 4957db96d56Sopenharmony_ci } 4967db96d56Sopenharmony_ci return old; 4977db96d56Sopenharmony_ci} 4987db96d56Sopenharmony_ci 4997db96d56Sopenharmony_ci#define _Py_atomic_load_32bit(ATOMIC_VAL, ORDER) \ 5007db96d56Sopenharmony_ci _Py_atomic_load_32bit_impl((volatile int*)&((ATOMIC_VAL)->_value), (ORDER)) 5017db96d56Sopenharmony_ci 5027db96d56Sopenharmony_ci#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ 5037db96d56Sopenharmony_ci if (sizeof((ATOMIC_VAL)->_value) == 8) { \ 5047db96d56Sopenharmony_ci _Py_atomic_store_64bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } else { \ 5057db96d56Sopenharmony_ci _Py_atomic_store_32bit((ATOMIC_VAL), (NEW_VAL), (ORDER)) } 5067db96d56Sopenharmony_ci 5077db96d56Sopenharmony_ci#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ 5087db96d56Sopenharmony_ci ( \ 5097db96d56Sopenharmony_ci sizeof((ATOMIC_VAL)->_value) == 8 ? \ 5107db96d56Sopenharmony_ci _Py_atomic_load_64bit((ATOMIC_VAL), (ORDER)) : \ 5117db96d56Sopenharmony_ci _Py_atomic_load_32bit((ATOMIC_VAL), (ORDER)) \ 5127db96d56Sopenharmony_ci ) 5137db96d56Sopenharmony_ci#endif 5147db96d56Sopenharmony_ci#else /* !gcc x86 !_msc_ver */ 5157db96d56Sopenharmony_citypedef enum _Py_memory_order { 5167db96d56Sopenharmony_ci _Py_memory_order_relaxed, 5177db96d56Sopenharmony_ci _Py_memory_order_acquire, 5187db96d56Sopenharmony_ci _Py_memory_order_release, 5197db96d56Sopenharmony_ci _Py_memory_order_acq_rel, 5207db96d56Sopenharmony_ci _Py_memory_order_seq_cst 5217db96d56Sopenharmony_ci} _Py_memory_order; 5227db96d56Sopenharmony_ci 5237db96d56Sopenharmony_citypedef struct _Py_atomic_address { 5247db96d56Sopenharmony_ci uintptr_t _value; 5257db96d56Sopenharmony_ci} _Py_atomic_address; 5267db96d56Sopenharmony_ci 5277db96d56Sopenharmony_citypedef struct _Py_atomic_int { 5287db96d56Sopenharmony_ci int _value; 5297db96d56Sopenharmony_ci} _Py_atomic_int; 5307db96d56Sopenharmony_ci/* Fall back to other compilers and processors by assuming that simple 5317db96d56Sopenharmony_ci volatile accesses are atomic. This is false, so people should port 5327db96d56Sopenharmony_ci this. */ 5337db96d56Sopenharmony_ci#define _Py_atomic_signal_fence(/*memory_order*/ ORDER) ((void)0) 5347db96d56Sopenharmony_ci#define _Py_atomic_thread_fence(/*memory_order*/ ORDER) ((void)0) 5357db96d56Sopenharmony_ci#define _Py_atomic_store_explicit(ATOMIC_VAL, NEW_VAL, ORDER) \ 5367db96d56Sopenharmony_ci ((ATOMIC_VAL)->_value = NEW_VAL) 5377db96d56Sopenharmony_ci#define _Py_atomic_load_explicit(ATOMIC_VAL, ORDER) \ 5387db96d56Sopenharmony_ci ((ATOMIC_VAL)->_value) 5397db96d56Sopenharmony_ci#endif 5407db96d56Sopenharmony_ci 5417db96d56Sopenharmony_ci/* Standardized shortcuts. */ 5427db96d56Sopenharmony_ci#define _Py_atomic_store(ATOMIC_VAL, NEW_VAL) \ 5437db96d56Sopenharmony_ci _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_seq_cst) 5447db96d56Sopenharmony_ci#define _Py_atomic_load(ATOMIC_VAL) \ 5457db96d56Sopenharmony_ci _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_seq_cst) 5467db96d56Sopenharmony_ci 5477db96d56Sopenharmony_ci/* Python-local extensions */ 5487db96d56Sopenharmony_ci 5497db96d56Sopenharmony_ci#define _Py_atomic_store_relaxed(ATOMIC_VAL, NEW_VAL) \ 5507db96d56Sopenharmony_ci _Py_atomic_store_explicit((ATOMIC_VAL), (NEW_VAL), _Py_memory_order_relaxed) 5517db96d56Sopenharmony_ci#define _Py_atomic_load_relaxed(ATOMIC_VAL) \ 5527db96d56Sopenharmony_ci _Py_atomic_load_explicit((ATOMIC_VAL), _Py_memory_order_relaxed) 5537db96d56Sopenharmony_ci 5547db96d56Sopenharmony_ci#ifdef __cplusplus 5557db96d56Sopenharmony_ci} 5567db96d56Sopenharmony_ci#endif 5577db96d56Sopenharmony_ci#endif /* Py_ATOMIC_H */ 558