From b28363a8381fd4e93d1254e71486e0185a84c9c5 Mon Sep 17 00:00:00 2001 From: John Hawthorn Date: Fri, 28 Mar 2025 22:23:48 -0700 Subject: [PATCH] Work on ATOMIC_VALUE_SET --- include/ruby/atomic.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/include/ruby/atomic.h b/include/ruby/atomic.h index 18072f4810..e0977d21aa 100644 --- a/include/ruby/atomic.h +++ b/include/ruby/atomic.h @@ -315,6 +315,19 @@ typedef unsigned int rb_atomic_t; #define RUBY_ATOMIC_PTR_CAS(var, oldval, newval) \ RBIMPL_CAST(rbimpl_atomic_ptr_cas((void **)&(var), (void *)(oldval), (void *)(newval))) +/** + * Identical to #RUBY_ATOMIC_SET, except it expects its arguments are + * ::VALUE. There are cases where ::rb_atomic_t is 32bit while ::VALUE is + * 64bit. This should be used for pointer related operations to support such + * platforms. + * + * @param var A variable of ::VALUE. + * @param val Value to set. + * @post `var` holds `val`. + */ +#define RUBY_ATOMIC_VALUE_SET(var, val) \ + rbimpl_atomic_value_set(&(var), (val)) + /** * Identical to #RUBY_ATOMIC_EXCHANGE, except it expects its arguments are * ::VALUE. There are cases where ::rb_atomic_t is 32bit while ::VALUE is @@ -730,6 +743,23 @@ rbimpl_atomic_size_exchange(volatile size_t *ptr, size_t val) #endif } +RBIMPL_ATTR_ARTIFICIAL() +RBIMPL_ATTR_NOALIAS() +RBIMPL_ATTR_NONNULL((1)) +static inline void +rbimpl_atomic_size_set(volatile size_t *ptr, size_t val) +{ +#if 0 + +#elif defined(HAVE_GCC_ATOMIC_BUILTINS) + __atomic_store_n(ptr, val, __ATOMIC_SEQ_CST); + +#else + rbimpl_atomic_size_exchange(ptr, val); + +#endif +} + RBIMPL_ATTR_ARTIFICIAL() RBIMPL_ATTR_NOALIAS() RBIMPL_ATTR_NONNULL((1)) @@ -772,6 +802,19 @@ rbimpl_atomic_value_exchange(volatile VALUE *ptr, VALUE val) return RBIMPL_CAST((VALUE)sret); } +RBIMPL_ATTR_ARTIFICIAL() +RBIMPL_ATTR_NOALIAS() +RBIMPL_ATTR_NONNULL((1)) +static inline void +rbimpl_atomic_value_set(volatile VALUE *ptr, VALUE val) +{ + RBIMPL_STATIC_ASSERT(sizeof_value, sizeof *ptr == sizeof(size_t)); + + const size_t sval = RBIMPL_CAST((size_t)val); + volatile size_t *const sptr = RBIMPL_CAST((volatile size_t *)ptr); + rbimpl_atomic_size_set(sptr, sval); +} + RBIMPL_ATTR_ARTIFICIAL() RBIMPL_ATTR_NOALIAS() RBIMPL_ATTR_NONNULL((1))