From: Bruno Haible Date: Sun, 21 Jan 2024 14:59:32 +0000 (+0100) Subject: asyncsafe-spin: Fix link error on various platforms. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=fd41ed12aaf5bbdca22ac6c26c7f3dfd0e831fb4;p=gnulib.git asyncsafe-spin: Fix link error on various platforms. * m4/atomic-cas.m4: New file. * lib/asyncsafe-spin.c: Test HAVE_ATOMIC_COMPARE_AND_SWAP_GCC41 instead of a condition that considers only __sparc__, __ANDROID__, __ibmxl__. * lib/pthread-spin.c: Likewise. * lib/simple-atomic.c: Likewise. * modules/asyncsafe-spin (Files): Add m4/atomic-cas.m4. (configure.ac): Require gl_ATOMIC_COMPARE_AND_SWAP. * modules/pthread-spin: Likewise. * modules/simple-atomic: Likewise. --- diff --git a/ChangeLog b/ChangeLog index 505af2fae8..de1fcc40da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2024-01-21 Bruno Haible + + asyncsafe-spin: Fix link error on various platforms. + * m4/atomic-cas.m4: New file. + * lib/asyncsafe-spin.c: Test HAVE_ATOMIC_COMPARE_AND_SWAP_GCC41 instead + of a condition that considers only __sparc__, __ANDROID__, __ibmxl__. + * lib/pthread-spin.c: Likewise. + * lib/simple-atomic.c: Likewise. + * modules/asyncsafe-spin (Files): Add m4/atomic-cas.m4. + (configure.ac): Require gl_ATOMIC_COMPARE_AND_SWAP. + * modules/pthread-spin: Likewise. + * modules/simple-atomic: Likewise. + 2024-01-18 Bruno Haible get-rusage-data: Avoid test failure on NetBSD 9.3. diff --git a/lib/asyncsafe-spin.c b/lib/asyncsafe-spin.c index c4e7d711a1..63352184ae 100644 --- a/lib/asyncsafe-spin.c +++ b/lib/asyncsafe-spin.c @@ -1,5 +1,5 @@ /* Spin locks for communication between threads and signal handlers. - Copyright (C) 2020-2023 Free Software Foundation, Inc. + Copyright (C) 2020-2024 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -134,11 +134,10 @@ do_unlock (asyncsafe_spinlock_t *lock) # endif # elif (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) \ - && !(defined __sun && defined __sparc__) && !defined __ANDROID__) \ - || __clang_major__ >= 3) \ - && !defined __ibmxl__ -/* Use GCC built-ins (available in GCC >= 4.1, except on Solaris/SPARC and - Android, and clang >= 3.0). + || __clang_major__ >= 3) \ + && HAVE_ATOMIC_COMPARE_AND_SWAP_GCC41) +/* Use GCC built-ins (available on many platforms with GCC >= 4.1 or + clang >= 3.0). Documentation: */ diff --git a/lib/pthread-spin.c b/lib/pthread-spin.c index 4031975f0b..26caa72496 100644 --- a/lib/pthread-spin.c +++ b/lib/pthread-spin.c @@ -1,5 +1,5 @@ /* POSIX spin locks. - Copyright (C) 2010-2023 Free Software Foundation, Inc. + Copyright (C) 2010-2024 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -163,10 +163,10 @@ pthread_spin_destroy (pthread_spinlock_t *lock) } # elif (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) \ - && !defined __ANDROID__) \ - || __clang_major__ >= 3) \ - && !defined __ibmxl__ -/* Use GCC built-ins (available in GCC >= 4.1 and clang >= 3.0). + || __clang_major__ >= 3) \ + && HAVE_ATOMIC_COMPARE_AND_SWAP_GCC41) +/* Use GCC built-ins (available on many platforms with GCC >= 4.1 or + clang >= 3.0). Documentation: */ diff --git a/lib/simple-atomic.c b/lib/simple-atomic.c index 1f43bd771c..656b4bdc19 100644 --- a/lib/simple-atomic.c +++ b/lib/simple-atomic.c @@ -1,5 +1,5 @@ /* Simple atomic operations for multithreading. - Copyright (C) 2020-2023 Free Software Foundation, Inc. + Copyright (C) 2020-2024 Free Software Foundation, Inc. This file is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -67,11 +67,10 @@ atomic_compare_and_swap_ptr (uintptr_t volatile *vp, require to link with -latomic. */ # if (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) \ - && !(defined __sun && defined __sparc__) && !defined __ANDROID__) \ - || __clang_major__ >= 3) \ - && !defined __ibmxl__ -/* Use GCC built-ins (available in GCC >= 4.1, except on Solaris/SPARC and - Android, and clang >= 3.0). + || __clang_major__ >= 3) \ + && HAVE_ATOMIC_COMPARE_AND_SWAP_GCC41) +/* Use GCC built-ins (available on many platforms with GCC >= 4.1 or + clang >= 3.0). Documentation: */ diff --git a/m4/atomic-cas.m4 b/m4/atomic-cas.m4 new file mode 100644 index 0000000000..fa246150e0 --- /dev/null +++ b/m4/atomic-cas.m4 @@ -0,0 +1,84 @@ +# atomic-cas.m4 serial 1 +dnl Copyright (C) 2024 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Determines whether the atomic compare-and-swap operations, officially +# supported in GCC >= 4.1 and clang >= 3.0, are actually available. +# These primitives are documented in +# +# without platform restrictions. But they are not actually available +# everywhere: +# * On some platforms, __sync_bool_compare_and_swap does not expand +# to standalone inline code, but to a call to a function +# '__sync_bool_compare_and_swap_4' (assuming a 32-bit value). +# This is the case on +# - arm, for all gcc versions +# - hppa, hppa64, for all gcc versions +# - i386 (without '-march=i486'), for all gcc versions +# - sparc (32-bit, for certain CPU models), for all gcc versions +# - m68k, for gcc < 4.7 +# - mips, for gcc < 4.3 +# This can be seen by compiling this piece of code +# ---------------------------------------------------------------- +# int cmpxchg (int* value, int comp_val, int new_val) +# { +# return __sync_val_compare_and_swap (value, comp_val, new_val); +# } +# ---------------------------------------------------------------- +# with option -S, using a (native or cross-) compiler. +# * The function __sync_bool_compare_and_swap_4 is meant to be included +# in libgcc. And indeed, libgcc contains the source code for this +# function on +# - arm, for gcc versions >= 4.7, but only for Linux +# and (for gcc >= 5) FreeBSD, +# - hppa, hppa64, for gcc versions >= 4.7, but only for Linux +# and (for gcc >= 13) NetBSD, OpenBSD, hppa64 HP-UX +# - i386, never at all +# - sparc, never at all +# - m68k, for gcc versions >= 4.7, but only for Linux +# - mips, never at all +# * The NetBSD C library provides this function on +# - arm, arm64, +# - i386, +# - sparc, +# - m68k, +# - riscv64. +# Other C libraries (e.g. glibc, musl libc) do not provide this function. +# So, the use of these primitives results in a link error on: +# - arm, with gcc versions >= 4.1, < 4.7 on all systems except NetBSD, +# with gcc versions >= 4.7, < 5 on FreeBSD, OpenBSD, Android, +# with gcc versions >= 5 on OpenBSD, Android, +# - hppa, hppa64, with gcc versions >= 4.1, < 4.7 on all systems, +# with gcc versions >= 4.7, < 13 on NetBSD, OpenBSD, +# - i386 (without '-march=i486'), with gcc versions >= 4.1 +# on all systems except NetBSD, +# - sparc (32-bit, for certain CPU models), with gcc versions >= 4.1 +# on all systems except NetBSD, +# - m68k, with gcc versions >= 4.1, < 4.7 on all systems except NetBSD, +# - mips, with gcc versions >= 4.1, < 4.3 on all systems. +# Additionally, link errors can occur if - such as on glibc systems - the libgcc +# functions are distributed through glibc, but the glibc version is older than +# the gcc version. +AC_DEFUN([gl_ATOMIC_COMPARE_AND_SWAP], +[ + AC_CACHE_CHECK([for __sync_bool_compare_and_swap], + [gl_cv_builtin_sync_bool_compare_and_swap], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[int cmpxchg (int* value, int comp_val, int new_val) + { + return __sync_val_compare_and_swap (value, comp_val, new_val); + } + ]], + [[]]) + ], + [gl_cv_builtin_sync_bool_compare_and_swap=yes], + [gl_cv_builtin_sync_bool_compare_and_swap=no]) + ]) + if test $gl_cv_builtin_sync_bool_compare_and_swap = yes; then + AC_DEFINE([HAVE_ATOMIC_COMPARE_AND_SWAP_GCC41], [1], + [Define to 1 if the GCC 4.1 primitives for atomic compare-and-swap can be used.]) + fi +]) diff --git a/modules/asyncsafe-spin b/modules/asyncsafe-spin index fc734928db..ffb2429e65 100644 --- a/modules/asyncsafe-spin +++ b/modules/asyncsafe-spin @@ -4,6 +4,7 @@ Spin locks for communication between threads and signal handlers. Files: lib/asyncsafe-spin.h lib/asyncsafe-spin.c +m4/atomic-cas.m4 Depends-on: signal-h @@ -15,6 +16,7 @@ sparcv8+ configure.ac: AC_REQUIRE([AC_C_INLINE]) AC_CHECK_HEADERS_ONCE([pthread.h]) +AC_REQUIRE([gl_ATOMIC_COMPARE_AND_SWAP]) Makefile.am: lib_SOURCES += asyncsafe-spin.c diff --git a/modules/pthread-spin b/modules/pthread-spin index 35e3aa701e..36b6180c90 100644 --- a/modules/pthread-spin +++ b/modules/pthread-spin @@ -4,6 +4,7 @@ POSIX spin locks. Files: lib/pthread-spin.c m4/pthread-spin.m4 +m4/atomic-cas.m4 Depends-on: pthread-h @@ -15,6 +16,7 @@ gl_PTHREAD_SPIN gl_CONDITIONAL([GL_COND_OBJ_PTHREAD_SPIN], [test $HAVE_PTHREAD_SPIN_INIT = 0 || test $REPLACE_PTHREAD_SPIN_INIT = 1]) gl_PTHREAD_MODULE_INDICATOR([pthread-spin]) +AC_REQUIRE([gl_ATOMIC_COMPARE_AND_SWAP]) Makefile.am: if GL_COND_OBJ_PTHREAD_SPIN diff --git a/modules/simple-atomic b/modules/simple-atomic index 5f3f63d109..8558620580 100644 --- a/modules/simple-atomic +++ b/modules/simple-atomic @@ -4,6 +4,7 @@ Simple atomic operations for multithreading. Files: lib/simple-atomic.h lib/simple-atomic.c +m4/atomic-cas.m4 Depends-on: stdint @@ -11,6 +12,7 @@ sparcv8+ configure.ac: AC_CHECK_HEADERS_ONCE([pthread.h]) +AC_REQUIRE([gl_ATOMIC_COMPARE_AND_SWAP]) Makefile.am: lib_SOURCES += simple-atomic.c