Ruby 3.5.0dev (2025-06-08 revision d0b5f3155406e8243b78e4cedd3a38710c7c323c)
ruby_atomic.h (d0b5f3155406e8243b78e4cedd3a38710c7c323c)
1#ifndef INTERNAL_ATOMIC_H
2#define INTERNAL_ATOMIC_H
3
4#include "ruby/atomic.h"
5
6/* shim macros only */
7#define ATOMIC_ADD(var, val) RUBY_ATOMIC_ADD(var, val)
8#define ATOMIC_CAS(var, oldval, newval) RUBY_ATOMIC_CAS(var, oldval, newval)
9#define ATOMIC_DEC(var) RUBY_ATOMIC_DEC(var)
10#define ATOMIC_EXCHANGE(var, val) RUBY_ATOMIC_EXCHANGE(var, val)
11#define ATOMIC_FETCH_ADD(var, val) RUBY_ATOMIC_FETCH_ADD(var, val)
12#define ATOMIC_FETCH_SUB(var, val) RUBY_ATOMIC_FETCH_SUB(var, val)
13#define ATOMIC_INC(var) RUBY_ATOMIC_INC(var)
14#define ATOMIC_OR(var, val) RUBY_ATOMIC_OR(var, val)
15#define ATOMIC_PTR_CAS(var, oldval, newval) RUBY_ATOMIC_PTR_CAS(var, oldval, newval)
16#define ATOMIC_PTR_EXCHANGE(var, val) RUBY_ATOMIC_PTR_EXCHANGE(var, val)
17#define ATOMIC_SET(var, val) RUBY_ATOMIC_SET(var, val)
18#define ATOMIC_SIZE_ADD(var, val) RUBY_ATOMIC_SIZE_ADD(var, val)
19#define ATOMIC_SIZE_CAS(var, oldval, newval) RUBY_ATOMIC_SIZE_CAS(var, oldval, newval)
20#define ATOMIC_SIZE_DEC(var) RUBY_ATOMIC_SIZE_DEC(var)
21#define ATOMIC_SIZE_EXCHANGE(var, val) RUBY_ATOMIC_SIZE_EXCHANGE(var, val)
22#define ATOMIC_SIZE_INC(var) RUBY_ATOMIC_SIZE_INC(var)
23#define ATOMIC_SIZE_SUB(var, val) RUBY_ATOMIC_SIZE_SUB(var, val)
24#define ATOMIC_SUB(var, val) RUBY_ATOMIC_SUB(var, val)
25#define ATOMIC_VALUE_CAS(var, oldval, val) RUBY_ATOMIC_VALUE_CAS(var, oldval, val)
26#define ATOMIC_VALUE_EXCHANGE(var, val) RUBY_ATOMIC_VALUE_EXCHANGE(var, val)
27
28static inline rb_atomic_t
29rbimpl_atomic_load_relaxed(volatile rb_atomic_t *ptr)
30{
31#if defined(HAVE_GCC_ATOMIC_BUILTINS)
32 return __atomic_load_n(ptr, __ATOMIC_RELAXED);
33#else
34 return *ptr;
35#endif
36}
37#define ATOMIC_LOAD_RELAXED(var) rbimpl_atomic_load_relaxed(&(var))
38
39static inline uint64_t
40rbimpl_atomic_u64_load_relaxed(const volatile uint64_t *value)
41{
42#if defined(HAVE_GCC_ATOMIC_BUILTINS_64)
43 return __atomic_load_n(value, __ATOMIC_RELAXED);
44#elif defined(_WIN32)
45 uint64_t val = *value;
46 return InterlockedCompareExchange64(RBIMPL_CAST((uint64_t *)value), val, val);
47#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
48 uint64_t val = *value;
49 return atomic_cas_64(value, val, val);
50#else
51 return *value;
52#endif
53}
54#define ATOMIC_U64_LOAD_RELAXED(var) rbimpl_atomic_u64_load_relaxed(&(var))
55
56static inline void
57rbimpl_atomic_u64_set_relaxed(volatile uint64_t *address, uint64_t value)
58{
59#if defined(HAVE_GCC_ATOMIC_BUILTINS_64)
60 __atomic_store_n(address, value, __ATOMIC_RELAXED);
61#elif defined(_WIN32)
62 InterlockedExchange64(address, value);
63#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
64 atomic_swap_64(address, value);
65#else
66 *address = value;
67#endif
68}
69#define ATOMIC_U64_SET_RELAXED(var, val) rbimpl_atomic_u64_set_relaxed(&(var), val)
70
71#endif
Atomic operations.
std::atomic< unsigned > rb_atomic_t
Type that is eligible for atomic operations.
Definition atomic.h:69