27#include "ruby/internal/config.h"
33#ifdef HAVE_SYS_TYPES_H
34# include <sys/types.h>
38# pragma intrinsic(_InterlockedOr)
39#elif defined(__sun) && defined(HAVE_ATOMIC_H)
44#include "ruby/backward/2/limits.h"
49#include "ruby/internal/cast.h"
59#if defined(__DOXYGEN__) || defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
60# define RUBY_ATOMIC_GENERIC_MACRO 1
68#if defined(__DOXYGEN__)
70#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
72#elif defined(HAVE_GCC_SYNC_BUILTINS)
78#elif defined(__sun) && defined(HAVE_ATOMIC_H)
80#elif defined(HAVE_STDATOMIC_H)
81# include <stdatomic.h>
84# error No atomic operation found
88#if defined(HAVE_GCC_ATOMIC_BUILTINS)
89# define RBIMPL_ATOMIC_RELAXED __ATOMIC_RELAXED
90# define RBIMPL_ATOMIC_ACQUIRE __ATOMIC_ACQUIRE
91# define RBIMPL_ATOMIC_RELEASE __ATOMIC_RELEASE
92# define RBIMPL_ATOMIC_ACQ_REL __ATOMIC_ACQ_REL
93# define RBIMPL_ATOMIC_SEQ_CST __ATOMIC_SEQ_CST
94#elif defined(HAVE_STDATOMIC_H)
95# define RBIMPL_ATOMIC_RELAXED memory_order_relaxed
96# define RBIMPL_ATOMIC_ACQUIRE memory_order_acquire
97# define RBIMPL_ATOMIC_RELEASE memory_order_release
98# define RBIMPL_ATOMIC_ACQ_REL memory_order_acq_rel
99# define RBIMPL_ATOMIC_SEQ_CST memory_order_seq_cst
102# define RBIMPL_ATOMIC_RELAXED 0
103# define RBIMPL_ATOMIC_ACQUIRE 1
104# define RBIMPL_ATOMIC_RELEASE 2
105# define RBIMPL_ATOMIC_ACQ_REL 3
106# define RBIMPL_ATOMIC_SEQ_CST 4
118#define RUBY_ATOMIC_FETCH_ADD(var, val) rbimpl_atomic_fetch_add(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
129#define RUBY_ATOMIC_FETCH_SUB(var, val) rbimpl_atomic_fetch_sub(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
141#define RUBY_ATOMIC_OR(var, val) rbimpl_atomic_or(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
152#define RUBY_ATOMIC_EXCHANGE(var, val) rbimpl_atomic_exchange(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
165#define RUBY_ATOMIC_CAS(var, oldval, newval) \
166 rbimpl_atomic_cas(&(var), (oldval), (newval), RBIMPL_ATOMIC_SEQ_CST, RBIMPL_ATOMIC_SEQ_CST)
175#define RUBY_ATOMIC_LOAD(var) rbimpl_atomic_load(&(var), RBIMPL_ATOMIC_SEQ_CST)
185#define RUBY_ATOMIC_SET(var, val) rbimpl_atomic_store(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
195#define RUBY_ATOMIC_ADD(var, val) rbimpl_atomic_add(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
205#define RUBY_ATOMIC_SUB(var, val) rbimpl_atomic_sub(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
214#define RUBY_ATOMIC_INC(var) rbimpl_atomic_inc(&(var), RBIMPL_ATOMIC_SEQ_CST)
223#define RUBY_ATOMIC_DEC(var) rbimpl_atomic_dec(&(var), RBIMPL_ATOMIC_SEQ_CST)
235#define RUBY_ATOMIC_SIZE_FETCH_ADD(var, val) rbimpl_atomic_size_fetch_add(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
246#define RUBY_ATOMIC_SIZE_INC(var) rbimpl_atomic_size_inc(&(var), RBIMPL_ATOMIC_SEQ_CST)
257#define RUBY_ATOMIC_SIZE_DEC(var) rbimpl_atomic_size_dec(&(var), RBIMPL_ATOMIC_SEQ_CST)
270#define RUBY_ATOMIC_SIZE_EXCHANGE(var, val) \
271 rbimpl_atomic_size_exchange(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
284#define RUBY_ATOMIC_SIZE_CAS(var, oldval, newval) \
285 rbimpl_atomic_size_cas(&(var), (oldval), (newval), RBIMPL_ATOMIC_SEQ_CST, RBIMPL_ATOMIC_SEQ_CST)
295#define RUBY_ATOMIC_SIZE_LOAD(var) rbimpl_atomic_size_load(&(var), RBIMPL_ATOMIC_SEQ_CST)
307#define RUBY_ATOMIC_SIZE_ADD(var, val) rbimpl_atomic_size_add(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
319#define RUBY_ATOMIC_SIZE_SUB(var, val) rbimpl_atomic_size_sub(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
337#define RUBY_ATOMIC_PTR_EXCHANGE(var, val) \
338 RBIMPL_CAST(rbimpl_atomic_ptr_exchange((void **)&(var), (void *)val, RBIMPL_ATOMIC_SEQ_CST))
348#define RUBY_ATOMIC_PTR_LOAD(var) \
349 RBIMPL_CAST(rbimpl_atomic_ptr_load((void **)&var, RBIMPL_ATOMIC_SEQ_CST))
361#define RUBY_ATOMIC_PTR_SET(var, val) \
362 rbimpl_atomic_ptr_store((volatile void **)&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
375#define RUBY_ATOMIC_PTR_CAS(var, oldval, newval) \
376 RBIMPL_CAST(rbimpl_atomic_ptr_cas((void **)&(var), (void *)(oldval), (void *)(newval), RBIMPL_ATOMIC_SEQ_CST, RBIMPL_ATOMIC_SEQ_CST))
388#define RUBY_ATOMIC_VALUE_SET(var, val) \
389 rbimpl_atomic_value_store(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
402#define RUBY_ATOMIC_VALUE_EXCHANGE(var, val) \
403 rbimpl_atomic_value_exchange(&(var), (val), RBIMPL_ATOMIC_SEQ_CST)
416#define RUBY_ATOMIC_VALUE_CAS(var, oldval, newval) \
417 rbimpl_atomic_value_cas(&(var), (oldval), (newval), RBIMPL_ATOMIC_SEQ_CST, RBIMPL_ATOMIC_SEQ_CST)
429#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
430 return __atomic_fetch_add(ptr, val, memory_order);
432#elif defined(HAVE_GCC_SYNC_BUILTINS)
433 return __sync_fetch_and_add(ptr, val);
436 return InterlockedExchangeAdd(ptr, val);
438#elif defined(__sun) && defined(HAVE_ATOMIC_H)
445 return atomic_add_int_nv(ptr, val) - val;
447#elif defined(HAVE_STDATOMIC_H)
448 return atomic_fetch_add_explicit((_Atomic
volatile rb_atomic_t *)ptr, val, memory_order);
451# error Unsupported platform.
460rbimpl_atomic_size_fetch_add(volatile
size_t *ptr,
size_t val,
int memory_order)
465#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
466 return __atomic_fetch_add(ptr, val, memory_order);
468#elif defined(HAVE_GCC_SYNC_BUILTINS)
469 return __sync_fetch_and_add(ptr, val);
472 return InterlockedExchangeAdd64(RBIMPL_CAST((LONG64 *)ptr), val);
474#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
477 atomic_add_long(ptr, val);
479#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
483 return rbimpl_atomic_fetch_add(tmp, val, memory_order);
485#elif defined(HAVE_STDATOMIC_H)
486 return atomic_fetch_add_explicit((_Atomic
volatile size_t *)ptr, val, memory_order);
489# error Unsupported platform.
502#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
508 __atomic_add_fetch(ptr, val, memory_order);
510#elif defined(HAVE_GCC_SYNC_BUILTINS)
511 __sync_add_and_fetch(ptr, val);
519 InterlockedExchangeAdd(ptr, val);
521#elif defined(__sun) && defined(HAVE_ATOMIC_H)
524 atomic_add_int(ptr, val);
526#elif defined(HAVE_STDATOMIC_H)
527 atomic_fetch_add_explicit((_Atomic
volatile rb_atomic_t *)ptr, val, memory_order);
530# error Unsupported platform.
538rbimpl_atomic_size_add(volatile
size_t *ptr,
size_t val,
int memory_order)
543#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
544 __atomic_add_fetch(ptr, val, memory_order);
546#elif defined(HAVE_GCC_SYNC_BUILTINS)
547 __sync_add_and_fetch(ptr, val);
551 InterlockedExchangeAdd64(RBIMPL_CAST((LONG64 *)ptr), val);
553#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
556 atomic_add_long(ptr, val);
558#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
562 rbimpl_atomic_add(tmp, val, memory_order);
564#elif defined(HAVE_STDATOMIC_H)
565 atomic_fetch_add_explicit((_Atomic
volatile size_t *)ptr, val, memory_order);
568# error Unsupported platform.
576rbimpl_atomic_inc(volatile
rb_atomic_t *ptr,
int memory_order)
581#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
582 rbimpl_atomic_add(ptr, 1, memory_order);
585 InterlockedIncrement(ptr);
587#elif defined(__sun) && defined(HAVE_ATOMIC_H)
588 atomic_inc_uint(ptr);
590#elif defined(HAVE_STDATOMIC_H)
591 rbimpl_atomic_add(ptr, 1, memory_order);
594# error Unsupported platform.
602rbimpl_atomic_size_inc(volatile
size_t *ptr,
int memory_order)
607#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
608 rbimpl_atomic_size_add(ptr, 1, memory_order);
611 InterlockedIncrement64(RBIMPL_CAST((LONG64 *)ptr));
613#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
614 atomic_inc_ulong(ptr);
616#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
619 rbimpl_atomic_size_add(ptr, 1, memory_order);
621#elif defined(HAVE_STDATOMIC_H)
622 rbimpl_atomic_size_add(ptr, 1, memory_order);
625# error Unsupported platform.
638#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
639 return __atomic_fetch_sub(ptr, val, memory_order);
641#elif defined(HAVE_GCC_SYNC_BUILTINS)
642 return __sync_fetch_and_sub(ptr, val);
646 return InterlockedExchangeAdd(ptr, -val);
648#elif defined(__sun) && defined(HAVE_ATOMIC_H)
650 const signed neg = -1;
652 return atomic_add_int_nv(ptr, neg * val) + val;
654#elif defined(HAVE_STDATOMIC_H)
655 return atomic_fetch_sub_explicit((_Atomic
volatile rb_atomic_t *)ptr, val, memory_order);
658# error Unsupported platform.
671#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
672 __atomic_sub_fetch(ptr, val, memory_order);
674#elif defined(HAVE_GCC_SYNC_BUILTINS)
675 __sync_sub_and_fetch(ptr, val);
678 InterlockedExchangeAdd(ptr, -val);
680#elif defined(__sun) && defined(HAVE_ATOMIC_H)
681 const signed neg = -1;
683 atomic_add_int(ptr, neg * val);
685#elif defined(HAVE_STDATOMIC_H)
686 atomic_fetch_sub_explicit((_Atomic
volatile rb_atomic_t *)ptr, val, memory_order);
689# error Unsupported platform.
697rbimpl_atomic_size_sub(volatile
size_t *ptr,
size_t val,
int memory_order)
702#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
703 __atomic_sub_fetch(ptr, val, memory_order);
705#elif defined(HAVE_GCC_SYNC_BUILTINS)
706 __sync_sub_and_fetch(ptr, val);
709 const ssize_t neg = -1;
710 InterlockedExchangeAdd64(RBIMPL_CAST((LONG64 *)ptr), neg * val);
712#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
713 const signed neg = -1;
715 atomic_add_long(ptr, neg * val);
717#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
721 rbimpl_atomic_sub(tmp, val, memory_order);
723#elif defined(HAVE_STDATOMIC_H)
724 atomic_fetch_sub_explicit((_Atomic
volatile size_t *)ptr, val, memory_order);
727# error Unsupported platform.
735rbimpl_atomic_dec(volatile
rb_atomic_t *ptr,
int memory_order)
740#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
741 rbimpl_atomic_sub(ptr, 1, memory_order);
744 InterlockedDecrement(ptr);
746#elif defined(__sun) && defined(HAVE_ATOMIC_H)
747 atomic_dec_uint(ptr);
749#elif defined(HAVE_STDATOMIC_H)
750 rbimpl_atomic_sub(ptr, 1, memory_order);
753# error Unsupported platform.
761rbimpl_atomic_size_dec(volatile
size_t *ptr,
int memory_order)
766#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_SYNC_BUILTINS)
767 rbimpl_atomic_size_sub(ptr, 1, memory_order);
770 InterlockedDecrement64(RBIMPL_CAST((LONG64 *)ptr));
772#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
773 atomic_dec_ulong(ptr);
775#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
778 rbimpl_atomic_size_sub(ptr, 1, memory_order);
780#elif defined(HAVE_STDATOMIC_H)
781 rbimpl_atomic_size_sub(ptr, 1, memory_order);
784# error Unsupported platform.
797#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
798 __atomic_or_fetch(ptr, val, memory_order);
800#elif defined(HAVE_GCC_SYNC_BUILTINS)
801 __sync_or_and_fetch(ptr, val);
803#elif defined(_MSC_VER)
804 _InterlockedOr(ptr, val);
806#elif defined(__sun) && defined(HAVE_ATOMIC_H)
807 atomic_or_uint(ptr, val);
809#elif !defined(_WIN32) && defined(HAVE_STDATOMIC_H)
810 atomic_fetch_or_explicit((_Atomic
volatile rb_atomic_t *)ptr, val, memory_order);
813# error Unsupported platform.
826#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
827 return __atomic_exchange_n(ptr, val, memory_order);
829#elif defined(HAVE_GCC_SYNC_BUILTINS)
830 return __sync_lock_test_and_set(ptr, val);
833 return InterlockedExchange(ptr, val);
835#elif defined(__sun) && defined(HAVE_ATOMIC_H)
836 return atomic_swap_uint(ptr, val);
838#elif defined(HAVE_STDATOMIC_H)
839 return atomic_exchange_explicit((_Atomic
volatile rb_atomic_t *)ptr, val, memory_order);
842# error Unsupported platform.
850rbimpl_atomic_size_exchange(volatile
size_t *ptr,
size_t val,
int memory_order)
855#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
856 return __atomic_exchange_n(ptr, val, memory_order);
858#elif defined(HAVE_GCC_SYNC_BUILTINS)
859 return __sync_lock_test_and_set(ptr, val);
862 return InterlockedExchange64(RBIMPL_CAST((LONG64 *)ptr), val);
864#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
865 return atomic_swap_ulong(ptr, val);
867#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
871 const rb_atomic_t ret = rbimpl_atomic_exchange(tmp, val, memory_order);
872 return RBIMPL_CAST((
size_t)ret);
874#elif defined(HAVE_STDATOMIC_H)
875 return atomic_exchange_explicit((_Atomic
volatile size_t *)ptr, val, memory_order);
878# error Unsupported platform.
886rbimpl_atomic_size_store(volatile
size_t *ptr,
size_t val,
int memory_order)
891#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
892 __atomic_store_n(ptr, val, memory_order);
895 rbimpl_atomic_size_exchange(ptr, val, memory_order);
904rbimpl_atomic_ptr_exchange(
void *volatile *ptr, const
void *val,
int memory_order)
909#elif defined(InterlockedExchangePointer)
911 PVOID *pptr = RBIMPL_CAST((PVOID *)ptr);
912 PVOID pval = RBIMPL_CAST((PVOID)val);
913 return InterlockedExchangePointer(pptr, pval);
915#elif defined(__sun) && defined(HAVE_ATOMIC_H)
916 return atomic_swap_ptr(ptr, RBIMPL_CAST((
void *)val));
921 const size_t sval = RBIMPL_CAST((
size_t)val);
922 volatile size_t *
const sptr = RBIMPL_CAST((
volatile size_t *)ptr);
923 const size_t sret = rbimpl_atomic_size_exchange(sptr, sval, memory_order);
924 return RBIMPL_CAST((
void *)sret);
933rbimpl_atomic_ptr_store(volatile
void **ptr,
void *val,
int memory_order)
937 const size_t sval = RBIMPL_CAST((
size_t)val);
938 volatile size_t *
const sptr = RBIMPL_CAST((
volatile size_t *)ptr);
939 rbimpl_atomic_size_store(sptr, sval, memory_order);
946rbimpl_atomic_value_exchange(volatile
VALUE *ptr,
VALUE val,
int memory_order)
950 const size_t sval = RBIMPL_CAST((
size_t)val);
951 volatile size_t *
const sptr = RBIMPL_CAST((
volatile size_t *)ptr);
952 const size_t sret = rbimpl_atomic_size_exchange(sptr, sval, memory_order);
953 return RBIMPL_CAST((
VALUE)sret);
960rbimpl_atomic_value_store(volatile
VALUE *ptr,
VALUE val,
int memory_order)
964 const size_t sval = RBIMPL_CAST((
size_t)val);
965 volatile size_t *
const sptr = RBIMPL_CAST((
volatile size_t *)ptr);
966 rbimpl_atomic_size_store(sptr, sval, memory_order);
973rbimpl_atomic_load(volatile
rb_atomic_t *ptr,
int memory_order)
978#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
979 return __atomic_load_n(ptr, memory_order);
980#elif defined(_M_X64) && !defined(_M_ARM64EC)
984 return rbimpl_atomic_fetch_add(ptr, 0, memory_order);
997#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
998 __atomic_store_n(ptr, val, memory_order);
1002 rbimpl_atomic_exchange(ptr, val, memory_order);
1013 (void)success_memorder;
1014 (void)failure_memorder;
1017#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
1018 __atomic_compare_exchange_n(
1019 ptr, &oldval, newval, 0, success_memorder, failure_memorder);
1022#elif defined(HAVE_GCC_SYNC_BUILTINS)
1023 return __sync_val_compare_and_swap(ptr, oldval, newval);
1025#elif defined(_MSC_VER)
1026 return InterlockedCompareExchange(ptr, newval, oldval);
1028#elif defined(__sun) && defined(HAVE_ATOMIC_H)
1029 return atomic_cas_uint(ptr, oldval, newval);
1031#elif defined(HAVE_STDATOMIC_H)
1032 atomic_compare_exchange_strong_explicit(
1033 (_Atomic
volatile rb_atomic_t *)ptr, &oldval, newval, success_memorder, failure_memorder);
1037# error Unsupported platform.
1045rbimpl_atomic_size_cas(volatile
size_t *ptr,
size_t oldval,
size_t newval,
int success_memorder,
int failure_memorder)
1047 (void)success_memorder;
1048 (void)failure_memorder;
1051#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
1052 __atomic_compare_exchange_n(
1053 ptr, &oldval, newval, 0, success_memorder, failure_memorder);
1056#elif defined(HAVE_GCC_SYNC_BUILTINS)
1057 return __sync_val_compare_and_swap(ptr, oldval, newval);
1059#elif defined(_WIN64)
1060 return InterlockedCompareExchange64(RBIMPL_CAST((LONG64 *)ptr), newval, oldval);
1062#elif defined(__sun) && defined(HAVE_ATOMIC_H) && (defined(_LP64) || defined(_I32LPx))
1063 return atomic_cas_ulong(ptr, oldval, newval);
1065#elif defined(_WIN32) || (defined(__sun) && defined(HAVE_ATOMIC_H))
1069 return rbimpl_atomic_cas(tmp, oldval, newval, success_memorder, failure_memorder);
1071#elif defined(HAVE_STDATOMIC_H)
1072 atomic_compare_exchange_strong_explicit(
1073 (_Atomic
volatile size_t *)ptr, &oldval, newval, success_memorder, failure_memorder);
1077# error Unsupported platform.
1085rbimpl_atomic_size_load(volatile
size_t *ptr,
int memory_order)
1090#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
1091 return __atomic_load_n(ptr, memory_order);
1092#elif defined(_M_X64) && !defined(_M_ARM64EC)
1097 return rbimpl_atomic_size_cas(ptr, val, val, memory_order, memory_order);
1105rbimpl_atomic_ptr_cas(
void **ptr, const
void *oldval, const
void *newval,
int success_memorder,
int failure_memorder)
1107 (void)success_memorder;
1108 (void)failure_memorder;
1111#elif defined(InterlockedExchangePointer)
1114 PVOID *pptr = RBIMPL_CAST((PVOID *)ptr);
1115 PVOID pold = RBIMPL_CAST((PVOID)oldval);
1116 PVOID pnew = RBIMPL_CAST((PVOID)newval);
1117 return InterlockedCompareExchangePointer(pptr, pnew, pold);
1119#elif defined(__sun) && defined(HAVE_ATOMIC_H)
1120 void *pold = RBIMPL_CAST((
void *)oldval);
1121 void *pnew = RBIMPL_CAST((
void *)newval);
1122 return atomic_cas_ptr(ptr, pold, pnew);
1128 const size_t snew = RBIMPL_CAST((
size_t)newval);
1129 const size_t sold = RBIMPL_CAST((
size_t)oldval);
1130 volatile size_t *
const sptr = RBIMPL_CAST((
volatile size_t *)ptr);
1131 const size_t sret = rbimpl_atomic_size_cas(sptr, sold, snew, success_memorder, failure_memorder);
1132 return RBIMPL_CAST((
void *)sret);
1141rbimpl_atomic_ptr_load(
void **ptr,
int memory_order)
1146#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
1147 return __atomic_load_n(ptr, memory_order);
1148#elif defined(_M_X64) && !defined(_M_ARM64EC)
1149 return *RBIMPL_CAST((
void *
volatile *)ptr);
1152 return rbimpl_atomic_ptr_cas(ptr, val, val, memory_order, memory_order);
1160rbimpl_atomic_value_load(volatile
VALUE *ptr,
int memory_order)
1162 return RBIMPL_CAST((
VALUE)rbimpl_atomic_ptr_load((
void **)ptr, memory_order));
1169rbimpl_atomic_value_cas(volatile
VALUE *ptr,
VALUE oldval,
VALUE newval,
int success_memorder,
int failure_memorder)
1173 const size_t snew = RBIMPL_CAST((
size_t)newval);
1174 const size_t sold = RBIMPL_CAST((
size_t)oldval);
1175 volatile size_t *
const sptr = RBIMPL_CAST((
volatile size_t *)ptr);
1176 const size_t sret = rbimpl_atomic_size_cas(sptr, sold, snew, success_memorder, failure_memorder);
1177 return RBIMPL_CAST((
VALUE)sret);
Defines RBIMPL_ATTR_ARTIFICIAL.
#define RBIMPL_ATTR_ARTIFICIAL()
Wraps (or simulates) __attribute__((artificial))
#define RBIMPL_ASSERT_OR_ASSUME(...)
This is either RUBY_ASSERT or RBIMPL_ASSUME, depending on RUBY_DEBUG.
std::atomic< unsigned > rb_atomic_t
Type that is eligible for atomic operations.
Defines RBIMPL_COMPILER_SINCE.
Defines RBIMPL_ATTR_NONNULL.
#define RBIMPL_ATTR_NONNULL(list)
Wraps (or simulates) __attribute__((nonnull))
Defines RBIMPL_STATIC_ASSERT.
#define RBIMPL_STATIC_ASSERT
Wraps (or simulates) static_assert
Defines RBIMPL_ATTR_NOALIAS.
#define RBIMPL_ATTR_NOALIAS()
Wraps (or simulates) __declspec((noalias))
uintptr_t VALUE
Type that represents a Ruby object.