[PATCH 21/22] Define __HAVE_64B_ATOMICS from compiler support
Adhemerval Zanella
adhemerval.zanella@linaro.org
Thu Sep 11 13:49:47 GMT 2025
From: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
Now that atomic builtins are used by default, we can rely on the
compiler to define when to use 64-bit atomic operations.
It allows the use of 64-bit atomic operations on some 32-bit ABIs where
they were not previously enabled due to missing pre-processor handling:
hppa, mips64n32, s390, and sparcv9.
Co-authored-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
---
config.h.in | 3 +++
configure | 42 +++++++++++++++++++++++++++++
configure.ac | 27 +++++++++++++++++++
include/atomic.h | 5 ----
sysdeps/aarch64/atomic-machine.h | 1 -
sysdeps/alpha/atomic-machine.h | 2 --
sysdeps/arc/atomic-machine.h | 2 --
sysdeps/arm/atomic-machine.h | 1 -
sysdeps/csky/atomic-machine.h | 1 -
sysdeps/hppa/atomic-machine.h | 2 --
sysdeps/loongarch/atomic-machine.h | 1 -
sysdeps/m68k/atomic-machine.h | 3 ---
sysdeps/microblaze/atomic-machine.h | 2 --
sysdeps/mips/atomic-machine.h | 6 -----
sysdeps/or1k/atomic-machine.h | 1 -
sysdeps/powerpc/atomic-machine.h | 5 ----
sysdeps/riscv/atomic-machine.h | 1 -
sysdeps/s390/atomic-machine.h | 6 -----
sysdeps/sh/atomic-machine.h | 2 --
sysdeps/sparc/atomic-machine.h | 6 -----
sysdeps/x86/atomic-machine.h | 10 -------
21 files changed, 72 insertions(+), 57 deletions(-)
diff --git a/config.h.in b/config.h.in
index 8b4077f578..da22001920 100644
--- a/config.h.in
+++ b/config.h.in
@@ -216,6 +216,9 @@
/* An integer used to scale the timeout of test programs. */
#define TIMEOUTFACTOR 1
+/* Set to 1 if 64 bit atomics are supported. */
+#undef __HAVE_64B_ATOMICS 0
+
/*
*/
diff --git a/configure b/configure
index 222f04db22..b7d0d53c60 100755
--- a/configure
+++ b/configure
@@ -7676,6 +7676,48 @@ if test "$libc_cv_gcc_builtin_memset" = yes ; then
fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for 64-bit atomic support" >&5
+printf %s "checking for 64-bit atomic support... " >&6; }
+if test ${libc_cv_gcc_has_64b_atomics+y}
+then :
+ printf %s "(cached) " >&6
+else case e in #(
+ e) cat > conftest.c <<\EOF
+typedef struct { long long t; } X;
+extern void has_64b_atomics(void);
+void f(void)
+{
+ X x;
+ /* Use address of structure with 64-bit type. This avoids incorrect
+ implementations which return true even if long long is not 64-bit aligned.
+ This works on GCC and LLVM - other cases have bugs and they disagree. */
+ _Static_assert (__atomic_always_lock_free (sizeof (x), &x), "no_64b_atomics");
+}
+EOF
+if { ac_try='${CC-cc} -O2 -S conftest.c'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; };
+then
+ libc_cv_gcc_has_64b_atomics=yes
+else
+ libc_cv_gcc_has_64b_atomics=no
+fi
+rm -f conftest* ;;
+esac
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_has_64b_atomics" >&5
+printf "%s\n" "$libc_cv_gcc_has_64b_atomics" >&6; }
+if test "$libc_cv_gcc_has_64b_atomics" = yes; then
+ printf "%s\n" "#define __HAVE_64B_ATOMICS 1" >>confdefs.h
+
+else
+ printf "%s\n" "#define __HAVE_64B_ATOMICS 0" >>confdefs.h
+
+ fi
+
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for redirection of built-in functions" >&5
printf %s "checking for redirection of built-in functions... " >&6; }
if test ${libc_cv_gcc_builtin_redirection+y}
diff --git a/configure.ac b/configure.ac
index af57b0cbae..9dacdf5ee6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1484,6 +1484,33 @@ if test "$libc_cv_gcc_builtin_memset" = yes ; then
AC_DEFINE(HAVE_BUILTIN_MEMSET)
fi
+AC_CACHE_CHECK(for 64-bit atomic support, libc_cv_gcc_has_64b_atomics, [dnl
+cat > conftest.c <<\EOF
+typedef struct { long long t; } X;
+extern void has_64b_atomics(void);
+void f(void)
+{
+ X x;
+ /* Use address of structure with 64-bit type. This avoids incorrect
+ implementations which return true even if long long is not 64-bit aligned.
+ This works on GCC and LLVM - other cases have bugs and they disagree. */
+ _Static_assert (__atomic_always_lock_free (sizeof (x), &x), "no_64b_atomics");
+}
+EOF
+dnl
+if AC_TRY_COMMAND([${CC-cc} -O2 -S conftest.c]);
+then
+ libc_cv_gcc_has_64b_atomics=yes
+else
+ libc_cv_gcc_has_64b_atomics=no
+fi
+rm -f conftest* ])
+if test "$libc_cv_gcc_has_64b_atomics" = yes; then
+ AC_DEFINE(__HAVE_64B_ATOMICS, 1)
+else
+ AC_DEFINE(__HAVE_64B_ATOMICS, 0)
+ fi
+
AC_CACHE_CHECK(for redirection of built-in functions, libc_cv_gcc_builtin_redirection, [dnl
cat > conftest.c <<\EOF
extern char *strstr (const char *, const char *) __asm ("my_strstr");
diff --git a/include/atomic.h b/include/atomic.h
index eb85f48ecd..b193bde7c1 100644
--- a/include/atomic.h
+++ b/include/atomic.h
@@ -122,11 +122,6 @@
({ __typeof (x) __x; __asm ("" : "=r" (__x) : "0" (x)); __x; })
#endif
-/* This is equal to 1 iff the architecture supports 64b atomic operations. */
-#ifndef __HAVE_64B_ATOMICS
-#error Unable to determine if 64-bit atomics are present.
-#endif
-
/* The following functions are a subset of the atomic operations provided by
C11. Usually, a function named atomic_OP_MO(args) is equivalent to C11's
atomic_OP_explicit(args, memory_order_MO); exceptions noted below. */
diff --git a/sysdeps/aarch64/atomic-machine.h b/sysdeps/aarch64/atomic-machine.h
index f00c4607f3..002a800358 100644
--- a/sysdeps/aarch64/atomic-machine.h
+++ b/sysdeps/aarch64/atomic-machine.h
@@ -19,7 +19,6 @@
#ifndef _AARCH64_ATOMIC_MACHINE_H
#define _AARCH64_ATOMIC_MACHINE_H 1
-#define __HAVE_64B_ATOMICS 1
#define ATOMIC_EXCHANGE_USES_CAS 0
#endif
diff --git a/sysdeps/alpha/atomic-machine.h b/sysdeps/alpha/atomic-machine.h
index 198f5dc037..9844f13079 100644
--- a/sysdeps/alpha/atomic-machine.h
+++ b/sysdeps/alpha/atomic-machine.h
@@ -17,8 +17,6 @@
#include <stdint.h>
-#define __HAVE_64B_ATOMICS 1
-
/* XXX Is this actually correct? */
#define ATOMIC_EXCHANGE_USES_CAS 1
diff --git a/sysdeps/arc/atomic-machine.h b/sysdeps/arc/atomic-machine.h
index 096035840a..69b9328fc8 100644
--- a/sysdeps/arc/atomic-machine.h
+++ b/sysdeps/arc/atomic-machine.h
@@ -19,8 +19,6 @@
#ifndef _ARC_BITS_ATOMIC_H
#define _ARC_BITS_ATOMIC_H 1
-#define __HAVE_64B_ATOMICS 0
-
/* ARC does have legacy atomic EX reg, [mem] instruction but the micro-arch
is not as optimal as LLOCK/SCOND specially for SMP. */
#define ATOMIC_EXCHANGE_USES_CAS 1
diff --git a/sysdeps/arm/atomic-machine.h b/sysdeps/arm/atomic-machine.h
index f728de4ba5..7aee873371 100644
--- a/sysdeps/arm/atomic-machine.h
+++ b/sysdeps/arm/atomic-machine.h
@@ -16,5 +16,4 @@
License along with the GNU C Library. If not, see
<https://www.gnu.org/licenses/>. */
-#define __HAVE_64B_ATOMICS 0
#define ATOMIC_EXCHANGE_USES_CAS 1
diff --git a/sysdeps/csky/atomic-machine.h b/sysdeps/csky/atomic-machine.h
index 5d6f3d19ce..84468cd66e 100644
--- a/sysdeps/csky/atomic-machine.h
+++ b/sysdeps/csky/atomic-machine.h
@@ -19,7 +19,6 @@
#ifndef __CSKY_ATOMIC_H_
#define __CSKY_ATOMIC_H_
-#define __HAVE_64B_ATOMICS 0
#define ATOMIC_EXCHANGE_USES_CAS 1
#endif /* atomic-machine.h */
diff --git a/sysdeps/hppa/atomic-machine.h b/sysdeps/hppa/atomic-machine.h
index 839b8df596..92d386b748 100644
--- a/sysdeps/hppa/atomic-machine.h
+++ b/sysdeps/hppa/atomic-machine.h
@@ -18,8 +18,6 @@
#ifndef _ATOMIC_MACHINE_H
#define _ATOMIC_MACHINE_H 1
-#define __HAVE_64B_ATOMICS 0
-
/* XXX Is this actually correct? */
#define ATOMIC_EXCHANGE_USES_CAS 1
diff --git a/sysdeps/loongarch/atomic-machine.h b/sysdeps/loongarch/atomic-machine.h
index 7e10309932..20cc170735 100644
--- a/sysdeps/loongarch/atomic-machine.h
+++ b/sysdeps/loongarch/atomic-machine.h
@@ -19,7 +19,6 @@
#ifndef _LINUX_LOONGARCH_BITS_ATOMIC_H
#define _LINUX_LOONGARCH_BITS_ATOMIC_H 1
-#define __HAVE_64B_ATOMICS (__loongarch_grlen >= 64)
#define ATOMIC_EXCHANGE_USES_CAS 0
#endif /* bits/atomic.h */
diff --git a/sysdeps/m68k/atomic-machine.h b/sysdeps/m68k/atomic-machine.h
index 49a65d6d99..8542affba0 100644
--- a/sysdeps/m68k/atomic-machine.h
+++ b/sysdeps/m68k/atomic-machine.h
@@ -19,9 +19,6 @@
#define _M68K_ATOMIC_MACHINE_H 1
#if defined __mc68020__ || defined __mcoldfire__
-/* If we have just non-atomic operations, we can as well make them wide. */
-# define __HAVE_64B_ATOMICS 0
-
/* XXX Is this actually correct? */
# define ATOMIC_EXCHANGE_USES_CAS 1
#else
diff --git a/sysdeps/microblaze/atomic-machine.h b/sysdeps/microblaze/atomic-machine.h
index d5f6f7e462..8c04235b69 100644
--- a/sysdeps/microblaze/atomic-machine.h
+++ b/sysdeps/microblaze/atomic-machine.h
@@ -18,7 +18,5 @@
#include <sysdep.h>
-#define __HAVE_64B_ATOMICS 0
-
/* XXX Is this actually correct? */
#define ATOMIC_EXCHANGE_USES_CAS 1
diff --git a/sysdeps/mips/atomic-machine.h b/sysdeps/mips/atomic-machine.h
index f19310006b..9294fb76d9 100644
--- a/sysdeps/mips/atomic-machine.h
+++ b/sysdeps/mips/atomic-machine.h
@@ -27,12 +27,6 @@
#define MIPS_PUSH_MIPS2
#endif
-#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32
-#define __HAVE_64B_ATOMICS 0
-#else
-#define __HAVE_64B_ATOMICS 1
-#endif
-
/* MIPS is an LL/SC machine. However, XLP has a direct atomic exchange
instruction which will be used by __atomic_exchange_n. */
#ifdef _MIPS_ARCH_XLP
diff --git a/sysdeps/or1k/atomic-machine.h b/sysdeps/or1k/atomic-machine.h
index 8dac0e4ced..51bc8a0ff4 100644
--- a/sysdeps/or1k/atomic-machine.h
+++ b/sysdeps/or1k/atomic-machine.h
@@ -19,7 +19,6 @@
#ifndef __OR1K_ATOMIC_H_
#define __OR1K_ATOMIC_H_
-#define __HAVE_64B_ATOMICS 0
#define ATOMIC_EXCHANGE_USES_CAS 1
#endif /* atomic-machine.h */
diff --git a/sysdeps/powerpc/atomic-machine.h b/sysdeps/powerpc/atomic-machine.h
index e32408a09d..988cc4f435 100644
--- a/sysdeps/powerpc/atomic-machine.h
+++ b/sysdeps/powerpc/atomic-machine.h
@@ -19,11 +19,6 @@
#ifndef _POWERPC_ATOMIC_MACHINE_H
#define _POWERPC_ATOMIC_MACHINE_H 1
-#if __WORDSIZE == 64
-# define __HAVE_64B_ATOMICS 1
-#else
-# define __HAVE_64B_ATOMICS 0
-#endif
#define ATOMIC_EXCHANGE_USES_CAS 1
/* Used on pthread_spin_{try}lock. */
diff --git a/sysdeps/riscv/atomic-machine.h b/sysdeps/riscv/atomic-machine.h
index c5d39c1be7..5d2ad331cc 100644
--- a/sysdeps/riscv/atomic-machine.h
+++ b/sysdeps/riscv/atomic-machine.h
@@ -21,7 +21,6 @@
#ifdef __riscv_atomic
-# define __HAVE_64B_ATOMICS (__riscv_xlen >= 64)
# define ATOMIC_EXCHANGE_USES_CAS 0
/* Miscellaneous. */
diff --git a/sysdeps/s390/atomic-machine.h b/sysdeps/s390/atomic-machine.h
index 6f20dce802..b1646d1b07 100644
--- a/sysdeps/s390/atomic-machine.h
+++ b/sysdeps/s390/atomic-machine.h
@@ -15,10 +15,4 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#ifdef __s390x__
-# define __HAVE_64B_ATOMICS 1
-#else
-# define __HAVE_64B_ATOMICS 0
-#endif
-
#define ATOMIC_EXCHANGE_USES_CAS 1
diff --git a/sysdeps/sh/atomic-machine.h b/sysdeps/sh/atomic-machine.h
index b4ed894bdb..b012d6f056 100644
--- a/sysdeps/sh/atomic-machine.h
+++ b/sysdeps/sh/atomic-machine.h
@@ -16,7 +16,5 @@
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
-#define __HAVE_64B_ATOMICS 0
-
/* XXX Is this actually correct? */
#define ATOMIC_EXCHANGE_USES_CAS 1
diff --git a/sysdeps/sparc/atomic-machine.h b/sysdeps/sparc/atomic-machine.h
index a00d2ad1d3..a16f18fe57 100644
--- a/sysdeps/sparc/atomic-machine.h
+++ b/sysdeps/sparc/atomic-machine.h
@@ -19,12 +19,6 @@
#ifndef _ATOMIC_MACHINE_H
#define _ATOMIC_MACHINE_H 1
-#ifdef __arch64__
-# define __HAVE_64B_ATOMICS 1
-#else
-# define __HAVE_64B_ATOMICS 0
-#endif
-
/* XXX Is this actually correct? */
#define ATOMIC_EXCHANGE_USES_CAS __HAVE_64B_ATOMICS
diff --git a/sysdeps/x86/atomic-machine.h b/sysdeps/x86/atomic-machine.h
index 0051eede70..7c2ebfcee1 100644
--- a/sysdeps/x86/atomic-machine.h
+++ b/sysdeps/x86/atomic-machine.h
@@ -19,16 +19,6 @@
#ifndef _X86_ATOMIC_MACHINE_H
#define _X86_ATOMIC_MACHINE_H 1
-#ifdef __x86_64__
-# define __HAVE_64B_ATOMICS 1
-#else
-/* Since the Pentium, i386 CPUs have supported 64-bit atomics, but the
- i386 psABI supplement provides only 4-byte alignment for uint64_t
- inside structs, so it is currently not possible to use 64-bit
- atomics on this platform. */
-# define __HAVE_64B_ATOMICS 0
-#endif
-
#define ATOMIC_EXCHANGE_USES_CAS 0
#define atomic_spin_nop() __asm ("pause")
--
2.43.0
More information about the Libc-alpha
mailing list