Ruby 3.5.0dev (2025-08-14 revision c8233db22107adc77021d3f88e2b9d608b243b08)
ruby_atomic.h (c8233db22107adc77021d3f88e2b9d608b243b08)
1#ifndef INTERNAL_ATOMIC_H
2#define INTERNAL_ATOMIC_H
3
4#include "ruby/atomic.h"
5
6#define RUBY_ATOMIC_VALUE_LOAD(x) rbimpl_atomic_value_load(&(x), RBIMPL_ATOMIC_SEQ_CST)
7
8/* shim macros only */
9#define ATOMIC_ADD(var, val) RUBY_ATOMIC_ADD(var, val)
10#define ATOMIC_CAS(var, oldval, newval) RUBY_ATOMIC_CAS(var, oldval, newval)
11#define ATOMIC_DEC(var) RUBY_ATOMIC_DEC(var)
12#define ATOMIC_EXCHANGE(var, val) RUBY_ATOMIC_EXCHANGE(var, val)
13#define ATOMIC_FETCH_ADD(var, val) RUBY_ATOMIC_FETCH_ADD(var, val)
14#define ATOMIC_FETCH_SUB(var, val) RUBY_ATOMIC_FETCH_SUB(var, val)
15#define ATOMIC_INC(var) RUBY_ATOMIC_INC(var)
16#define ATOMIC_OR(var, val) RUBY_ATOMIC_OR(var, val)
17#define ATOMIC_PTR_CAS(var, oldval, newval) RUBY_ATOMIC_PTR_CAS(var, oldval, newval)
18#define ATOMIC_PTR_EXCHANGE(var, val) RUBY_ATOMIC_PTR_EXCHANGE(var, val)
19#define ATOMIC_SET(var, val) RUBY_ATOMIC_SET(var, val)
20#define ATOMIC_SIZE_ADD(var, val) RUBY_ATOMIC_SIZE_ADD(var, val)
21#define ATOMIC_SIZE_CAS(var, oldval, newval) RUBY_ATOMIC_SIZE_CAS(var, oldval, newval)
22#define ATOMIC_SIZE_DEC(var) RUBY_ATOMIC_SIZE_DEC(var)
23#define ATOMIC_SIZE_EXCHANGE(var, val) RUBY_ATOMIC_SIZE_EXCHANGE(var, val)
24#define ATOMIC_SIZE_INC(var) RUBY_ATOMIC_SIZE_INC(var)
25#define ATOMIC_SIZE_SUB(var, val) RUBY_ATOMIC_SIZE_SUB(var, val)
26#define ATOMIC_SUB(var, val) RUBY_ATOMIC_SUB(var, val)
27#define ATOMIC_VALUE_CAS(var, oldval, val) RUBY_ATOMIC_VALUE_CAS(var, oldval, val)
28#define ATOMIC_VALUE_EXCHANGE(var, val) RUBY_ATOMIC_VALUE_EXCHANGE(var, val)
29
30#define ATOMIC_LOAD_RELAXED(var) rbimpl_atomic_load(&(var), RBIMPL_ATOMIC_RELAXED)
31
32typedef RBIMPL_ALIGNAS(8) uint64_t rbimpl_atomic_uint64_t;
33
34static inline uint64_t
35rbimpl_atomic_u64_load_relaxed(const volatile rbimpl_atomic_uint64_t *value)
36{
37#if defined(HAVE_GCC_ATOMIC_BUILTINS_64)
38 return __atomic_load_n(value, __ATOMIC_RELAXED);
39#elif defined(_WIN32)
40 uint64_t val = *value;
41 return InterlockedCompareExchange64(RBIMPL_CAST((uint64_t *)value), val, val);
42#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
43 uint64_t val = *value;
44 return atomic_cas_64(value, val, val);
45#else
46 return *value;
47#endif
48}
49#define ATOMIC_U64_LOAD_RELAXED(var) rbimpl_atomic_u64_load_relaxed(&(var))
50
51static inline void
52rbimpl_atomic_u64_set_relaxed(volatile rbimpl_atomic_uint64_t *address, uint64_t value)
53{
54#if defined(HAVE_GCC_ATOMIC_BUILTINS_64)
55 __atomic_store_n(address, value, __ATOMIC_RELAXED);
56#elif defined(_WIN32)
57 InterlockedExchange64(address, value);
58#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
59 atomic_swap_64(address, value);
60#else
61 *address = value;
62#endif
63}
64#define ATOMIC_U64_SET_RELAXED(var, val) rbimpl_atomic_u64_set_relaxed(&(var), val)
65
66#endif
Atomic operations.
#define RBIMPL_ALIGNAS
Wraps (or simulates) alignas.
Definition stdalign.h:57
#define inline
Old Visual Studio versions do not support the inline keyword, so we need to define it to be __inline.
Definition defines.h:91