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