On 22/11/20 01:27 +0000, Jonathan Wakely via Libstdc++ wrote:
On Sat, 21 Nov 2020 at 23:55, David Edelsohn via Libstdc++
<libstd...@gcc.gnu.org> wrote:

I am seeing 93 new libstdc++ failures on AIX, even after Jonathan's
fixes.  And a few c++ failures with similar symptoms.  I'm not certain
that it is due to this patch, but it's the likely suspect.
Yes, it's that patch.

This should fix most of those errors, but I haven't finished testing
it, and can't commit it now anyway.

I've committed this now.

Tested powerpc64le-linux and (lightly) on powerpc-aix and
sparc-solaris.


commit 183ae52b226898cc34aa51d4153cf0c006212a8a
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Sun Nov 22 01:00:46 2020

    libstdc++: make atomic waiting depend on gthreads or futexes
    
    libstdc++-v3/ChangeLog:
    
            * include/bits/atomic_wait.h: Do not define anything unless
            gthreads or futexes are available.
            * include/bits/atomic_timed_wait.h: Likewise.
            * include/bits/semaphore_base.h: Likewise.
            * include/std/semaphore: Likewise.
            * include/bits/atomic_base.h (atomic_flag::wait)
            (atomic_flag::notify_one, atomic_flag::notify_all)
            (__atomic_base<I>::wait, __atomic_base<I>::notify_one)
            (__atomic_base<I>::notify_all, __atomic_base<P*>::wait)
            (__atomic_base<P*>::notify_one, __atomic_base<P*>::notify_all)
            (__atomic_impl::wait, __atomic_impl::notify_one)
            (__atomic_impl::notify_all, __atomic_float::wait)
            (__atomic_float::notify_one, __atomic_float::notify_all)
            (__atomic_ref::wait, __atomic_ref::notify_one)
            (__atomic_ref::notify_all): Only define if gthreads or futexes
            are available.
            * include/std/atomic (atomic::wait, atomic::notify_one)
            (atomic::notify_all): Likewise.
            * include/std/version (__cpp_lib_semaphore): Define
            conditionally.

diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
index 7de02f169977..d7db8612889e 100644
--- a/libstdc++-v3/include/bits/atomic_base.h
+++ b/libstdc++-v3/include/bits/atomic_base.h
@@ -230,6 +230,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return __v == __GCC_ATOMIC_TEST_AND_SET_TRUEVAL;
     }
 
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
     _GLIBCXX_ALWAYS_INLINE void
     wait(bool __old,
 	memory_order __m = memory_order_seq_cst) const noexcept
@@ -252,6 +253,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { std::__atomic_notify(&_M_i, true); }
 
     // TODO add const volatile overload
+#endif // GTHREADS || LINUX_FUTEX
 #endif // C++20
 
     _GLIBCXX_ALWAYS_INLINE void
@@ -603,6 +605,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
 #if __cplusplus > 201703L
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
       _GLIBCXX_ALWAYS_INLINE void
       wait(__int_type __old,
 	  memory_order __m = memory_order_seq_cst) const noexcept
@@ -625,6 +628,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { std::__atomic_notify(&_M_i, true); }
 
       // TODO add const volatile overload
+#endif // GTHREADS || LINUX_FUTEX
 #endif // C++2a
 
       _GLIBCXX_ALWAYS_INLINE __int_type
@@ -897,6 +901,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
 #if __cplusplus > 201703L
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
       _GLIBCXX_ALWAYS_INLINE void
       wait(__pointer_type __old,
 	   memory_order __m = memory_order_seq_cst) noexcept
@@ -919,6 +924,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { std::__atomic_notify(&_M_p, true); }
 
       // TODO add const volatile overload
+#endif // GTHREADS || LINUX_FUTEX
 #endif // C++2a
 
       _GLIBCXX_ALWAYS_INLINE __pointer_type
@@ -1010,6 +1016,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
 #if __cplusplus > 201703L
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
     template<typename _Tp>
       _GLIBCXX_ALWAYS_INLINE void
       wait(const _Tp* __ptr, _Val<_Tp> __old,
@@ -1034,6 +1041,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { std::__atomic_notify(__ptr, true); }
 
       // TODO add const volatile overload
+#endif // GTHREADS || LINUX_FUTEX
 #endif // C++2a
 
     template<typename _Tp>
@@ -1289,6 +1297,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 				       __cmpexch_failure_order(__order));
       }
 
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
       _GLIBCXX_ALWAYS_INLINE void
       wait(_Fp __old, memory_order __m = memory_order_seq_cst) const noexcept
       { __atomic_impl::wait(&_M_fp, __old, __m); }
@@ -1306,6 +1315,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { __atomic_impl::notify_all(&_M_fp); }
 
       // TODO add const volatile overload
+#endif // GTHREADS || LINUX_FUTEX
 
       value_type
       fetch_add(value_type __i,
@@ -1444,6 +1454,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 				       __cmpexch_failure_order(__order));
       }
 
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
       _GLIBCXX_ALWAYS_INLINE void
       wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
       { __atomic_impl::wait(_M_ptr, __old, __m); }
@@ -1461,6 +1472,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { __atomic_impl::notify_all(_M_ptr); }
 
       // TODO add const volatile overload
+#endif // GTHREADS || LINUX_FUTEX
 
     private:
       _Tp* _M_ptr;
@@ -1557,6 +1569,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 				       __cmpexch_failure_order(__order));
       }
 
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
       _GLIBCXX_ALWAYS_INLINE void
       wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
       { __atomic_impl::wait(_M_ptr, __old, __m); }
@@ -1574,6 +1587,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { __atomic_impl::notify_all(_M_ptr); }
 
       // TODO add const volatile overload
+#endif // GTHREADS || LINUX_FUTEX
 
       value_type
       fetch_add(value_type __i,
@@ -1730,6 +1744,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 				       __cmpexch_failure_order(__order));
       }
 
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
       _GLIBCXX_ALWAYS_INLINE void
       wait(_Fp __old, memory_order __m = memory_order_seq_cst) const noexcept
       { __atomic_impl::wait(_M_ptr, __old, __m); }
@@ -1747,6 +1762,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { __atomic_impl::notify_all(_M_ptr); }
 
       // TODO add const volatile overload
+#endif // GTHREADS || LINUX_FUTEX
 
       value_type
       fetch_add(value_type __i,
@@ -1857,6 +1873,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 				       __cmpexch_failure_order(__order));
       }
 
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
       _GLIBCXX_ALWAYS_INLINE void
       wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
       { __atomic_impl::wait(_M_ptr, __old, __m); }
@@ -1874,6 +1891,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { __atomic_impl::notify_all(_M_ptr); }
 
       // TODO add const volatile overload
+#endif // GTHREADS || LINUX_FUTEX
 
       _GLIBCXX_ALWAYS_INLINE value_type
       fetch_add(difference_type __d,
diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h b/libstdc++-v3/include/bits/atomic_timed_wait.h
index 405f7e93ca85..b13f8aa12861 100644
--- a/libstdc++-v3/include/bits/atomic_timed_wait.h
+++ b/libstdc++-v3/include/bits/atomic_timed_wait.h
@@ -33,6 +33,7 @@
 #pragma GCC system_header
 
 #include <bits/c++config.h>
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
 #include <bits/functional_hash.h>
 #include <bits/atomic_wait.h>
 
@@ -286,4 +287,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif
+#endif // GTHREADS || LINUX_FUTEX
+#endif // _GLIBCXX_ATOMIC_TIMED_WAIT_H
diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h
index 7b2682a577ef..a40cff124d7d 100644
--- a/libstdc++-v3/include/bits/atomic_wait.h
+++ b/libstdc++-v3/include/bits/atomic_wait.h
@@ -33,6 +33,7 @@
 #pragma GCC system_header
 
 #include <bits/c++config.h>
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
 #include <bits/functional_hash.h>
 #include <bits/gthr.h>
 #include <bits/std_mutex.h>
@@ -106,7 +107,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	  }
       }
 
-      template<typename _Tp>
+    template<typename _Tp>
       void
       __platform_notify(const _Tp* __addr, bool __all) noexcept
       {
@@ -175,11 +176,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       bool
       _M_waiting() const noexcept
-	{
-	  __platform_wait_t __res;
-	  __atomic_load(&_M_wait, &__res, __ATOMIC_ACQUIRE);
-	  return __res;
-	}
+      {
+	__platform_wait_t __res;
+	__atomic_load(&_M_wait, &__res, __ATOMIC_ACQUIRE);
+	return __res;
+      }
 
       void
       _M_notify(bool __all) noexcept
@@ -305,4 +306,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
-#endif
+#endif // GTHREADS || LINUX_FUTEX
+#endif // _GLIBCXX_ATOMIC_WAIT_H
diff --git a/libstdc++-v3/include/bits/semaphore_base.h b/libstdc++-v3/include/bits/semaphore_base.h
index 78a0b6ba26e6..5e29d3783fe1 100644
--- a/libstdc++-v3/include/bits/semaphore_base.h
+++ b/libstdc++-v3/include/bits/semaphore_base.h
@@ -33,6 +33,7 @@
 #pragma GCC system_header
 
 #include <bits/c++config.h>
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
 #include <bits/atomic_base.h>
 #include <bits/atomic_timed_wait.h>
 
@@ -161,30 +162,68 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	noexcept
       { return _M_try_acquire_until(__clock_t::now() + __rtime); }
 
-    private:
-      sem_t _M_semaphore;
-    };
+  private:
+    sem_t _M_semaphore;
+  };
 #endif // _GLIBCXX_HAVE_POSIX_SEMAPHORE
 
-    template<typename _Tp>
-      struct __atomic_semaphore
+  template<typename _Tp>
+    struct __atomic_semaphore
+    {
+      static_assert(std::is_integral_v<_Tp>);
+      static_assert(__gnu_cxx::__int_traits<_Tp>::__max
+		      <= __gnu_cxx::__int_traits<ptrdiff_t>::__max);
+      static constexpr ptrdiff_t _S_max = __gnu_cxx::__int_traits<_Tp>::__max;
+
+      explicit __atomic_semaphore(_Tp __count) noexcept
+	: _M_counter(__count)
       {
-	static_assert(std::is_integral_v<_Tp>);
-	static_assert(__gnu_cxx::__int_traits<_Tp>::__max
-			<= __gnu_cxx::__int_traits<ptrdiff_t>::__max);
-	static constexpr ptrdiff_t _S_max = __gnu_cxx::__int_traits<_Tp>::__max;
+	__glibcxx_assert(__count >= 0 && __count <= _S_max);
+      }
 
-	explicit __atomic_semaphore(_Tp __count) noexcept
-	  : _M_counter(__count)
-	{
-	  __glibcxx_assert(__count >= 0 && __count <= _S_max);
-	}
+      __atomic_semaphore(const __atomic_semaphore&) = delete;
+      __atomic_semaphore& operator=(const __atomic_semaphore&) = delete;
 
-	__atomic_semaphore(const __atomic_semaphore&) = delete;
-	__atomic_semaphore& operator=(const __atomic_semaphore&) = delete;
+      _GLIBCXX_ALWAYS_INLINE void
+      _M_acquire() noexcept
+      {
+	auto const __pred = [this]
+	  {
+	    auto __old = __atomic_impl::load(&this->_M_counter,
+			    memory_order::acquire);
+	    if (__old == 0)
+	      return false;
+	    return __atomic_impl::compare_exchange_strong(&this->_M_counter,
+		      __old, __old - 1,
+		      memory_order::acquire,
+		      memory_order::release);
+	  };
+	auto __old = __atomic_impl::load(&_M_counter, memory_order_relaxed);
+	std::__atomic_wait(&_M_counter, __old, __pred);
+      }
 
-	_GLIBCXX_ALWAYS_INLINE void
-	_M_acquire() noexcept
+      bool
+      _M_try_acquire() noexcept
+      {
+	auto __old = __atomic_impl::load(&_M_counter, memory_order::acquire);
+	auto const __pred = [this, __old]
+	  {
+	    if (__old == 0)
+	      return false;
+
+	    auto __prev = __old;
+	    return __atomic_impl::compare_exchange_weak(&this->_M_counter,
+		      __prev, __prev - 1,
+		      memory_order::acquire,
+		      memory_order::release);
+	  };
+	return std::__atomic_spin(__pred);
+      }
+
+      template<typename _Clock, typename _Duration>
+	_GLIBCXX_ALWAYS_INLINE bool
+	_M_try_acquire_until(const chrono::time_point<_Clock,
+			     _Duration>& __atime) noexcept
 	{
 	  auto const __pred = [this]
 	    {
@@ -193,51 +232,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	      if (__old == 0)
 		return false;
 	      return __atomic_impl::compare_exchange_strong(&this->_M_counter,
-			__old, __old - 1,
-			memory_order::acquire,
-			memory_order::release);
+			      __old, __old - 1,
+			      memory_order::acquire,
+			      memory_order::release);
 	    };
+
 	  auto __old = __atomic_impl::load(&_M_counter, memory_order_relaxed);
-	  std::__atomic_wait(&_M_counter, __old, __pred);
-	}
-
-	bool
-	_M_try_acquire() noexcept
-	{
-	  auto __old = __atomic_impl::load(&_M_counter, memory_order::acquire);
-	  auto const __pred = [this, __old]
-	    {
-	      if (__old == 0)
-		return false;
-
-	      auto __prev = __old;
-	      return __atomic_impl::compare_exchange_weak(&this->_M_counter,
-			__prev, __prev - 1,
-			memory_order::acquire,
-			memory_order::release);
-	    };
-	  return std::__atomic_spin(__pred);
-	}
-
-	template<typename _Clock, typename _Duration>
-	  _GLIBCXX_ALWAYS_INLINE bool
-	  _M_try_acquire_until(const chrono::time_point<_Clock,
-			       _Duration>& __atime) noexcept
-	  {
-	    auto const __pred = [this]
-	      {
-		auto __old = __atomic_impl::load(&this->_M_counter,
-				memory_order::acquire);
-		if (__old == 0)
-		  return false;
-		return __atomic_impl::compare_exchange_strong(&this->_M_counter,
-				__old, __old - 1,
-				memory_order::acquire,
-				memory_order::release);
-	      };
-
-	    auto __old = __atomic_impl::load(&_M_counter, memory_order_relaxed);
-	    return __atomic_wait_until(&_M_counter, __old, __pred, __atime);
+	  return __atomic_wait_until(&_M_counter, __old, __pred, __atime);
 	}
 
       template<typename _Rep, typename _Period>
@@ -299,4 +300,5 @@ template<ptrdiff_t __least_max_value>
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std
 
-#endif
+#endif // GTHREADS || LINUX_FUTEX
+#endif // _GLIBCXX_SEMAPHORE_BASE_H
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 5afe33b41d9b..fe4de244f858 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -165,6 +165,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
 
 #if __cplusplus > 201703L
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
     void wait(bool __old, memory_order __m = memory_order_seq_cst) const
       noexcept
     { _M_base.wait(__old, __m); }
@@ -176,6 +177,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     void notify_all() const noexcept
     { _M_base.notify_all(); }
+#endif // GTHREADS || LINUX_FUTEX
 #endif
   };
 
@@ -379,6 +381,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                        __cmpexch_failure_order(__m)); }
 
 #if __cplusplus > 201703L
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
     void wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
     {
       std::__atomic_wait(&_M_i, __old,
@@ -399,7 +402,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     void notify_all() const noexcept
     { std::__atomic_notify(&_M_i, true); }
-#endif
+#endif // GTHREADS || LINUX_FUTEX
+#endif // C++20
 
     };
 #undef _GLIBCXX20_INIT
@@ -640,6 +644,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
 #if __cplusplus > 201703L
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
     void wait(__pointer_type __old,
 	      memory_order __m = memory_order_seq_cst) noexcept
     { _M_b.wait(__old, __m); }
@@ -651,6 +656,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     void notify_all() const noexcept
     { _M_b.notify_all(); }
+#endif // GTHREADS || LINUX_FUTEX
 #endif
       __pointer_type
       fetch_add(ptrdiff_t __d,
@@ -1406,6 +1412,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 
 #if __cplusplus > 201703L
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
   template<typename _Tp>
     inline void
     atomic_wait(const atomic<_Tp>* __a,
@@ -1429,6 +1436,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     atomic_notify_all(atomic<_Tp>* __a) noexcept
     { __a->notify_all(); }
 
+#endif // GTHREADS || LINUX_FUTEX
 #endif // C++2a
 
   // Function templates for atomic_integral and atomic_pointer operations only.
diff --git a/libstdc++-v3/include/std/semaphore b/libstdc++-v3/include/std/semaphore
index b4facde4ea1f..f4b83ab6ae3f 100644
--- a/libstdc++-v3/include/std/semaphore
+++ b/libstdc++-v3/include/std/semaphore
@@ -32,14 +32,16 @@
 #pragma GCC system_header
 
 #if __cplusplus > 201703L
-#define __cpp_lib_semaphore 201907L
 #include <bits/semaphore_base.h>
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
 #include <ext/numeric_traits.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#define __cpp_lib_semaphore 201907L
+
   template<ptrdiff_t __least_max_value =
 			__gnu_cxx::__int_traits<ptrdiff_t>::__max>
     class counting_semaphore
@@ -88,5 +90,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
  using binary_semaphore = std::counting_semaphore<1>;
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
-#endif // __cplusplus > 201703L
+#endif // GTHREADS || LINUX_FUTEX
+#endif // C++20
 #endif // _GLIBCXX_SEMAPHORE
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index 42ed7cb74d38..cf0454dbaf84 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -226,7 +226,9 @@
 #if __cpp_lib_concepts
 # define __cpp_lib_ranges 201911L
 #endif
-#define __cpp_lib_semaphore 201907L
+#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX
+# define __cpp_lib_semaphore 201907L
+#endif
 #define __cpp_lib_shift 201806L
 #if __cpp_lib_concepts
 # define __cpp_lib_span 202002L

Reply via email to