Path: blob/main/Include/internal/pycore_atomic_funcs.h
12 views
/* Atomic functions: similar to pycore_atomic.h, but don't need1to declare variables as atomic.23Py_ssize_t type:45* value = _Py_atomic_size_get(&var)6* _Py_atomic_size_set(&var, value)78Use sequentially-consistent ordering (__ATOMIC_SEQ_CST memory order):9enforce total ordering with all other atomic functions.10*/11#ifndef Py_ATOMIC_FUNC_H12#define Py_ATOMIC_FUNC_H13#ifdef __cplusplus14extern "C" {15#endif1617#ifndef Py_BUILD_CORE18# error "this header requires Py_BUILD_CORE define"19#endif2021#if defined(_MSC_VER)22# include <intrin.h> // _InterlockedExchange()23#endif242526// Use builtin atomic operations in GCC >= 4.7 and clang27#ifdef HAVE_BUILTIN_ATOMIC2829static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)30{31return __atomic_load_n(var, __ATOMIC_SEQ_CST);32}3334static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)35{36__atomic_store_n(var, value, __ATOMIC_SEQ_CST);37}3839#elif defined(_MSC_VER)4041static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)42{43#if SIZEOF_VOID_P == 844Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var));45volatile __int64 *volatile_var = (volatile __int64 *)var;46__int64 old;47do {48old = *volatile_var;49} while(_InterlockedCompareExchange64(volatile_var, old, old) != old);50#else51Py_BUILD_ASSERT(sizeof(long) == sizeof(*var));52volatile long *volatile_var = (volatile long *)var;53long old;54do {55old = *volatile_var;56} while(_InterlockedCompareExchange(volatile_var, old, old) != old);57#endif58return old;59}6061static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)62{63#if SIZEOF_VOID_P == 864Py_BUILD_ASSERT(sizeof(__int64) == sizeof(*var));65volatile __int64 *volatile_var = (volatile __int64 *)var;66_InterlockedExchange64(volatile_var, value);67#else68Py_BUILD_ASSERT(sizeof(long) == sizeof(*var));69volatile long *volatile_var = (volatile long *)var;70_InterlockedExchange(volatile_var, value);71#endif72}7374#else75// Fallback implementation using volatile7677static inline Py_ssize_t _Py_atomic_size_get(Py_ssize_t *var)78{79volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var;80return *volatile_var;81}8283static inline void _Py_atomic_size_set(Py_ssize_t *var, Py_ssize_t value)84{85volatile Py_ssize_t *volatile_var = (volatile Py_ssize_t *)var;86*volatile_var = value;87}88#endif8990#ifdef __cplusplus91}92#endif93#endif /* Py_ATOMIC_FUNC_H */949596