diff options
Diffstat (limited to 'ruby_atomic.h')
| -rw-r--r-- | ruby_atomic.h | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/ruby_atomic.h b/ruby_atomic.h index ad53356f06..409b9bcfd2 100644 --- a/ruby_atomic.h +++ b/ruby_atomic.h @@ -2,6 +2,9 @@ #define INTERNAL_ATOMIC_H #include "ruby/atomic.h" +#ifdef HAVE_STDATOMIC_H +# include <stdatomic.h> +#endif #define RUBY_ATOMIC_VALUE_LOAD(x) rbimpl_atomic_value_load(&(x), RBIMPL_ATOMIC_SEQ_CST) @@ -43,6 +46,8 @@ rbimpl_atomic_u64_load_relaxed(const volatile rbimpl_atomic_uint64_t *value) uint64_t val = *value; return atomic_cas_64(value, val, val); #else + // TODO: stdatomic + return *value; #endif } @@ -58,9 +63,51 @@ rbimpl_atomic_u64_set_relaxed(volatile rbimpl_atomic_uint64_t *address, uint64_t #elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx)) atomic_swap_64(address, value); #else + // TODO: stdatomic + *address = value; #endif } #define ATOMIC_U64_SET_RELAXED(var, val) rbimpl_atomic_u64_set_relaxed(&(var), val) +static inline uint64_t +rbimpl_atomic_u64_fetch_add_relaxed(volatile rbimpl_atomic_uint64_t *value, uint64_t addend) +{ +#if defined(HAVE_GCC_ATOMIC_BUILTINS_64) + return __atomic_fetch_add(value, addend, __ATOMIC_RELAXED); +#elif defined(_WIN32) + return (uint64_t)InterlockedExchangeAdd64((LONG64 *)value, (LONG64)addend); +#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx)) + return atomic_add_64_nv(value, addend) - addend; +#else + // TODO: stdatomic + uint64_t prev = *value; + *value = prev + addend; + return prev; +#endif +} +#define ATOMIC_U64_FETCH_ADD_RELAXED(var, val) rbimpl_atomic_u64_fetch_add_relaxed(&(var), val) + +static inline uint64_t +rbimpl_atomic_u64_load_acquire(const volatile rbimpl_atomic_uint64_t *value) +{ +#if defined(HAVE_GCC_ATOMIC_BUILTINS_64) + return __atomic_load_n(value, __ATOMIC_ACQUIRE); +#else + return rbimpl_atomic_u64_load_relaxed(value); +#endif +} +#define ATOMIC_U64_LOAD_ACQUIRE(var) rbimpl_atomic_u64_load_acquire(&(var)) + +static inline void +rbimpl_atomic_u64_set_release(volatile rbimpl_atomic_uint64_t *address, uint64_t value) +{ +#if defined(HAVE_GCC_ATOMIC_BUILTINS_64) + __atomic_store_n(address, value, __ATOMIC_RELEASE); +#else + rbimpl_atomic_u64_set_relaxed(address, value); +#endif +} +#define ATOMIC_U64_SET_RELEASE(var, val) rbimpl_atomic_u64_set_release(&(var), val) + #endif |
