From c5f7d274d78a5ef6818bc5d344a1f27bf2f794c4 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 4 Jun 2025 13:35:39 +0900 Subject: [PATCH] Check for 64bit atomic operations May not be supported on some 32bit architectures. ``` /usr/lib/gcc-cross/m68k-linux-gnu/14/../../../../m68k-linux-gnu/bin/ld: ../../libruby-static.a(vm.o): in function `rbimpl_atomic_u64_set_relaxed': /home/ubuntu/build/ruby/master/m68k-linux/../src/ruby_atomic.h:60:(.text+0x2468): undefined reference to `__atomic_store_8' /usr/lib/gcc-cross/m68k-linux-gnu/14/../../../../m68k-linux-gnu/bin/ld: ../../libruby-static.a(vm.o): in function `rbimpl_atomic_u64_load_relaxed': /home/ubuntu/build/ruby/master/m68k-linux/../src/ruby_atomic.h:43:(.text+0x2950): undefined reference to `__atomic_load_8' ``` --- configure.ac | 12 ++++++++++++ ruby_atomic.h | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 938754b01f..7270bd5e8b 100644 --- a/configure.ac +++ b/configure.ac @@ -1743,6 +1743,18 @@ AS_IF([test "$GCC" = yes], [ [rb_cv_gcc_atomic_builtins=no])]) AS_IF([test "$rb_cv_gcc_atomic_builtins" = yes], [ AC_DEFINE(HAVE_GCC_ATOMIC_BUILTINS) + AC_CACHE_CHECK([for 64bit __atomic builtins], [rb_cv_gcc_atomic_builtins_64], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include + uint64_t atomic_var;]], + [[ + __atomic_load_n(&atomic_var, __ATOMIC_RELAXED); + __atomic_store_n(&atomic_var, 0, __ATOMIC_RELAXED); + ]])], + [rb_cv_gcc_atomic_builtins_64=yes], + [rb_cv_gcc_atomic_builtins_64=no])]) + AS_IF([test "$rb_cv_gcc_atomic_builtins_64" = yes], [ + AC_DEFINE(HAVE_GCC_ATOMIC_BUILTINS_64) + ]) ]) AC_CACHE_CHECK([for __sync builtins], [rb_cv_gcc_sync_builtins], [ diff --git a/ruby_atomic.h b/ruby_atomic.h index 5c9049e001..2b4c16ba07 100644 --- a/ruby_atomic.h +++ b/ruby_atomic.h @@ -39,7 +39,7 @@ rbimpl_atomic_load_relaxed(rb_atomic_t *ptr) static inline uint64_t rbimpl_atomic_u64_load_relaxed(const uint64_t *value) { -#if defined(HAVE_GCC_ATOMIC_BUILTINS) +#if defined(HAVE_GCC_ATOMIC_BUILTINS_64) return __atomic_load_n(value, __ATOMIC_RELAXED); #elif defined(_WIN32) uint64_t val = *value; @@ -56,7 +56,7 @@ rbimpl_atomic_u64_load_relaxed(const uint64_t *value) static inline void rbimpl_atomic_u64_set_relaxed(uint64_t *address, uint64_t value) { -#if defined(HAVE_GCC_ATOMIC_BUILTINS) +#if defined(HAVE_GCC_ATOMIC_BUILTINS_64) __atomic_store_n(address, value, __ATOMIC_RELAXED); #elif defined(_WIN32) InterlockedExchange64(address, value);