]> Savannah Git Hosting - gnulib.git/commitdiff
asyncsafe-spin: Fix link error on various platforms.
authorBruno Haible <bruno@clisp.org>
Sun, 21 Jan 2024 14:59:32 +0000 (15:59 +0100)
committerBruno Haible <bruno@clisp.org>
Wed, 31 Jan 2024 17:12:37 +0000 (18:12 +0100)
* 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.

ChangeLog
lib/asyncsafe-spin.c
lib/pthread-spin.c
lib/simple-atomic.c
m4/atomic-cas.m4 [new file with mode: 0644]
modules/asyncsafe-spin
modules/pthread-spin
modules/simple-atomic

index 505af2fae84f730e3f8d551696f8d875eecd697a..de1fcc40dac7af6c9795121c3b62724c19081c23 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2024-01-21  Bruno Haible  <bruno@clisp.org>
+
+       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  <bruno@clisp.org>
 
        get-rusage-data: Avoid test failure on NetBSD 9.3.
index c4e7d711a1f182440d11bfba16dac934f04719e6..63352184aeffd120be7ee322a7d326edef52d7b3 100644 (file)
@@ -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:
    <https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html>  */
 
index 4031975f0beb6091921dfe39d06ac113e76fa915..26caa72496b9be79131b9a58192a78e50ef118a1 100644 (file)
@@ -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:
    <https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html>  */
 
index 1f43bd771cbcae90b2a447ce17cd0ae81e104c18..656b4bdc19dcef4b83347225c67d58691c9e5be1 100644 (file)
@@ -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:
    <https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html>  */
 
diff --git a/m4/atomic-cas.m4 b/m4/atomic-cas.m4
new file mode 100644 (file)
index 0000000..fa24615
--- /dev/null
@@ -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
+# <https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html>
+# 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
+])
index fc734928db65198dd5387d6850799afd8b4d7698..ffb2429e65e9cbe4c8d7faf3e9563f379d4e6fe9 100644 (file)
@@ -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
index 35e3aa701ecd948aaa73cc99e8fb62c587f16023..36b6180c90a1d8d5316ec9d19b206eceb6e722c9 100644 (file)
@@ -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
index 5f3f63d109bfed9512736b601e69a5012ef2fae5..8558620580d631695a466ccd99d7ea68351c8fcf 100644 (file)
@@ -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