[PATCH] libstdc++: Add C++2a synchronization support

Thomas Rodgers trodgers@redhat.com
Mon Sep 28 21:29:49 GMT 2020


Jonathan Wakely writes:

> On 11/09/20 16:58 -0700, Thomas Rodgers wrote:
>>From: Thomas Rodgers <trodgers@redhat.com>
>>
>>This patch supercedes both the Add C++2a synchronization support patch
>>being replied to *and* the patch adding wait/notify_* to atomic_flag.
>>
>>Add support for -
>>  * atomic_flag::wait/notify_one/notify_all
>>  * atomic::wait/notify_one/notify_all
>>  * counting_semaphore
>>  * binary_semaphore
>>  * latch
>>
>>libstdc++-v3/ChangeLog:
>>
>>	* include/Makefile.am (bits_headers): Add new header.
>>	* include/Makefile.in: Regenerate.
>>	* include/bits/atomic_base.h (__atomic_flag::wait): Define.
>>	(__atomic_flag::notify_one): Likewise.
>>	(__atomic_flag::notify_all): Likewise.
>>	(__atomic_base<_Itp>::wait): Likewise.
>>	(__atomic_base<_Itp>::notify_one): Likewise.
>>	(__atomic_base<_Itp>::notify_all): Likewise.
>>	(__atomic_base<_Ptp*>::wait): Likewise.
>>	(__atomic_base<_Ptp*>::notify_one): Likewise.
>>	(__atomic_base<_Ptp*>::notify_all): Likewise.
>>	(__atomic_impl::wait): Likewise.
>>	(__atomic_impl::notify_one): Likewise.
>>	(__atomic_impl::notify_all): Likewise.
>>	(__atomic_float<_Fp>::wait): Likewise.
>>	(__atomic_float<_Fp>::notify_one): Likewise.
>>	(__atomic_float<_Fp>::notify_all): Likewise.
>>	(__atomic_ref<_Tp>::wait): Likewise.
>>	(__atomic_ref<_Tp>::notify_one): Likewise.
>>	(__atomic_ref<_Tp>::notify_all): Likewise.
>>	(atomic_wait<_Tp>): Likewise.
>>	(atomic_wait_explicit<_Tp>): Likewise.
>>	(atomic_notify_one<_Tp>): Likewise.
>>	(atomic_notify_all<_Tp>): Likewise.
>>	* include/bits/atomic_wait.h: New file.
>>	* include/bits/atomic_timed_wait.h: New file.
>>	* include/bits/semaphore_base.h: New file.
>>	* include/std/atomic (atomic<bool>::wait): Define.
>>	(atomic<bool>::wait_one): Likewise.
>>	(atomic<bool>::wait_all): Likewise.
>>	(atomic<_Tp>::wait): Likewise.
>>	(atomic<_Tp>::wait_one): Likewise.
>>	(atomic<_Tp>::wait_all): Likewise.
>>	(atomic<_Tp*>::wait): Likewise.
>>	(atomic<_Tp*>::wait_one): Likewise.
>>	(atomic<_Tp*>::wait_all): Likewise.
>>	* include/std/latch: New file.
>>	* include/std/semaphore: New file.
>>	* include/std/version: Add __cpp_lib_semaphore and
>>	__cpp_lib_latch defines.
>>	* testsuite/29_atomic/atomic/wait_notify/atomic_refs.cc: New test.
>>	* testsuite/29_atomic/atomic/wait_notify/bool.cc: Likewise.
>>	* testsuite/29_atomic/atomic/wait_notify/integrals.cc: Likewise.
>>	* testsuite/29_atomic/atomic/wait_notify/floats.cc: Likewise.
>>	* testsuite/29_atomic/atomic/wait_notify/pointers.cc: Likewise.
>>	* testsuite/29_atomic/atomic/wait_notify/generic.cc: Liekwise.
>>	* testsuite/29_atomic/atomic/wait_notify/generic.h: New File.
>>	* testsuite/29_atomics/atomic_flag/wait_notify/1.cc: New test.
>>	* testsuite/30_thread/semaphore/1.cc: New test.
>>	* testsuite/30_thread/semaphore/2.cc: Likewise.
>>	* testsuite/30_thread/semaphore/least_max_value_neg.cc: Likewise.
>>	* testsuite/30_thread/semaphore/try_acquire.cc: Likewise.
>>	* testsuite/30_thread/semaphore/try_acquire_for.cc: Likewise.
>>	* testsuite/30_thread/semaphore/try_acquire_posix.cc: Likewise.
>>	* testsuite/30_thread/semaphore/try_acquire_until.cc: Likewise.
>>	* testsuite/30_thread/latch/1.cc: New test.
>>	* testsuite/30_thread/latch/2.cc: New test.
>>	* testsuite/30_thread/latch/3.cc: New test.
>>---
>> libstdc++-v3/include/Makefile.am              |   5 +
>> libstdc++-v3/include/Makefile.in              |   5 +
>> libstdc++-v3/include/bits/atomic_base.h       | 195 +++++++++++-
>> libstdc++-v3/include/bits/atomic_timed_wait.h | 281 ++++++++++++++++
>> libstdc++-v3/include/bits/atomic_wait.h       | 301 ++++++++++++++++++
>> libstdc++-v3/include/bits/semaphore_base.h    | 283 ++++++++++++++++
>> libstdc++-v3/include/std/atomic               |  73 +++++
>> libstdc++-v3/include/std/latch                |  90 ++++++
>> libstdc++-v3/include/std/semaphore            |  92 ++++++
>> libstdc++-v3/include/std/version              |   2 +
>> .../atomic/wait_notify/atomic_refs.cc         | 103 ++++++
>> .../29_atomics/atomic/wait_notify/bool.cc     |  59 ++++
>> .../29_atomics/atomic/wait_notify/floats.cc   |  32 ++
>> .../29_atomics/atomic/wait_notify/generic.cc  |  31 ++
>> .../29_atomics/atomic/wait_notify/generic.h   | 160 ++++++++++
>> .../atomic/wait_notify/integrals.cc           |  65 ++++
>> .../29_atomics/atomic/wait_notify/pointers.cc |  59 ++++
>> .../29_atomics/atomic_flag/wait_notify/1.cc   |  61 ++++
>> libstdc++-v3/testsuite/30_threads/latch/1.cc  |  27 ++
>> libstdc++-v3/testsuite/30_threads/latch/2.cc  |  27 ++
>> libstdc++-v3/testsuite/30_threads/latch/3.cc  |  50 +++
>> .../testsuite/30_threads/semaphore/1.cc       |  27 ++
>> .../testsuite/30_threads/semaphore/2.cc       |  27 ++
>> .../semaphore/least_max_value_neg.cc          |  30 ++
>> .../30_threads/semaphore/try_acquire.cc       |  55 ++++
>> .../30_threads/semaphore/try_acquire_for.cc   |  85 +++++
>> .../30_threads/semaphore/try_acquire_posix.cc | 153 +++++++++
>> .../30_threads/semaphore/try_acquire_until.cc |  94 ++++++
>> 28 files changed, 2471 insertions(+), 1 deletion(-)
>> create mode 100644 libstdc++-v3/include/bits/atomic_timed_wait.h
>> create mode 100644 libstdc++-v3/include/bits/atomic_wait.h
>> create mode 100644 libstdc++-v3/include/bits/semaphore_base.h
>> create mode 100644 libstdc++-v3/include/std/latch
>> create mode 100644 libstdc++-v3/include/std/semaphore
>> create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/atomic_refs.cc
>> create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/bool.cc
>> create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/floats.cc
>> create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.cc
>> create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/generic.h
>> create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/integrals.cc
>> create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic/wait_notify/pointers.cc
>> create mode 100644 libstdc++-v3/testsuite/29_atomics/atomic_flag/wait_notify/1.cc
>> create mode 100644 libstdc++-v3/testsuite/30_threads/latch/1.cc
>> create mode 100644 libstdc++-v3/testsuite/30_threads/latch/2.cc
>> create mode 100644 libstdc++-v3/testsuite/30_threads/latch/3.cc
>> create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/1.cc
>> create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/2.cc
>> create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/least_max_value_neg.cc
>> create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/try_acquire.cc
>> create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_for.cc
>> create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_posix.cc
>> create mode 100644 libstdc++-v3/testsuite/30_threads/semaphore/try_acquire_until.cc
>>
>>diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
>>index c9df9a9d6c6..9b5b6ed0005 100644
>>--- a/libstdc++-v3/include/Makefile.am
>>+++ b/libstdc++-v3/include/Makefile.am
>>@@ -52,6 +52,7 @@ std_headers = \
>> 	${std_srcdir}/iostream \
>> 	${std_srcdir}/istream \
>> 	${std_srcdir}/iterator \
>>+	${std_srcdir}/latch \
>> 	${std_srcdir}/limits \
>> 	${std_srcdir}/list \
>> 	${std_srcdir}/locale \
>>@@ -69,6 +70,7 @@ std_headers = \
>> 	${std_srcdir}/ratio \
>> 	${std_srcdir}/regex \
>> 	${std_srcdir}/scoped_allocator \
>>+	${std_srcdir}/semaphore \
>> 	${std_srcdir}/set \
>> 	${std_srcdir}/shared_mutex \
>> 	${std_srcdir}/span \
>>@@ -101,6 +103,8 @@ bits_headers = \
>> 	${bits_srcdir}/allocated_ptr.h \
>> 	${bits_srcdir}/allocator.h \
>> 	${bits_srcdir}/atomic_base.h \
>>+	${bits_srcdir}/atomic_wait.h \
>>+	${bits_srcdir}/atomic_timed_wait.h \
>> 	${bits_srcdir}/atomic_futex.h \
>> 	${bits_srcdir}/basic_ios.h \
>> 	${bits_srcdir}/basic_ios.tcc \
>>@@ -175,6 +179,7 @@ bits_headers = \
>> 	${bits_srcdir}/regex_compiler.tcc \
>> 	${bits_srcdir}/regex_executor.h \
>> 	${bits_srcdir}/regex_executor.tcc \
>>+	${bits_srcdir}/semaphore_base.h \
>> 	${bits_srcdir}/shared_ptr.h \
>> 	${bits_srcdir}/shared_ptr_atomic.h \
>> 	${bits_srcdir}/shared_ptr_base.h \
>>diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h
>>index 2cdd2bd6cae..dd4db926592 100644
>>--- a/libstdc++-v3/include/bits/atomic_base.h
>>+++ b/libstdc++-v3/include/bits/atomic_base.h
>>@@ -37,6 +37,10 @@
>> #include <bits/atomic_lockfree_defines.h>
>> #include <bits/move.h>
>>
>>+#if __cplusplus > 201703L
>>+#include <bits/atomic_wait.h>
>>+#endif
>>+
>> #ifndef _GLIBCXX_ALWAYS_INLINE
>> #define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
>> #endif
>>@@ -134,7 +138,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>       return __ret;
>>     }
>>
>>-
>>   // Base types for atomics.
>>   template<typename _IntTp>
>>     struct __atomic_base;
>>@@ -226,6 +229,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>       __atomic_load(&_M_i, &__v, int(__m));
>>       return __v == __GCC_ATOMIC_TEST_AND_SET_TRUEVAL;
>>     }
>>+
>>+    _GLIBCXX_ALWAYS_INLINE void
>>+    wait(bool __old,
>>+	memory_order __m = memory_order_seq_cst) const noexcept
>>+    {
>>+      std::__atomic_wait(&_M_i, __old,
>>+			 [__m, this, __old]()
>>+			 { return this->test(__m) != __old; });
>>+    }
>>+
>>+    // TODO add const volatile overload
>>+
>>+    _GLIBCXX_ALWAYS_INLINE void
>>+    notify_one() const noexcept
>>+    { std::__atomic_notify(&_M_i, false); }
>>+
>>+    // TODO add const volatile overload
>>+
>>+    _GLIBCXX_ALWAYS_INLINE void
>>+    notify_all() const noexcept
>>+    { std::__atomic_notify(&_M_i, true); }
>>+
>>+    // TODO add const volatile overload
>> #endif // C++20
>>
>>     _GLIBCXX_ALWAYS_INLINE void
>>@@ -576,6 +602,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> 				       __cmpexch_failure_order(__m));
>>       }
>>
>>+#if __cplusplus > 201703L
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      wait(__int_type __old,
>>+	  memory_order __m = memory_order_seq_cst) const noexcept
>>+      {
>>+	std::__atomic_wait(&_M_i, __old,
>>+			   [__m, this, __old]
>>+			   { return this->load(__m) != __old; });
>>+      }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_one() const noexcept
>>+      { std::__atomic_notify(&_M_i, false); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_all() const noexcept
>>+      { std::__atomic_notify(&_M_i, true); }
>>+
>>+      // TODO add const volatile overload
>>+#endif // C++2a
>>+
>>       _GLIBCXX_ALWAYS_INLINE __int_type
>>       fetch_add(__int_type __i,
>> 		memory_order __m = memory_order_seq_cst) noexcept
>>@@ -845,6 +896,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> 					   int(__m1), int(__m2));
>>       }
>>
>>+#if __cplusplus > 201703L
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      wait(__pointer_type __old,
>>+	   memory_order __m = memory_order_seq_cst) noexcept
>>+      {
>>+	std::__atomic_wait(&_M_p, __old,
>>+		      [__m, this, __old]()
>>+		      { return this->load(__m) != __old; });
>>+      }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_one() const noexcept
>>+      { std::__atomic_notify(&_M_p, false); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_all() const noexcept
>>+      { std::__atomic_notify(&_M_p, true); }
>>+
>>+      // TODO add const volatile overload
>>+#endif // C++2a
>>+
>>       _GLIBCXX_ALWAYS_INLINE __pointer_type
>>       fetch_add(ptrdiff_t __d,
>> 		memory_order __m = memory_order_seq_cst) noexcept
>>@@ -933,6 +1009,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> 					 int(__success), int(__failure));
>>       }
>>
>>+#if __cplusplus > 201703L
>>+    template<typename _Tp>
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      wait(const _Tp* __ptr, _Val<_Tp> __old,
>>+	   memory_order __m = memory_order_seq_cst) noexcept
>>+      {
>>+	std::__atomic_wait(__ptr, __old,
>>+	    [=]() { return load(__ptr, __m) == __old; });
>>+      }
>>+
>>+      // TODO add const volatile overload
>>+
>>+    template<typename _Tp>
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_one(const _Tp* __ptr) noexcept
>>+      { std::__atomic_notify(__ptr, false); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+    template<typename _Tp>
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_all(const _Tp* __ptr) noexcept
>>+      { std::__atomic_notify(__ptr, true); }
>>+
>>+      // TODO add const volatile overload
>>+#endif // C++2a
>>+
>>     template<typename _Tp>
>>       _GLIBCXX_ALWAYS_INLINE _Tp
>>       fetch_add(_Tp* __ptr, _Diff<_Tp> __i, memory_order __m) noexcept
>>@@ -1186,6 +1289,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> 				       __cmpexch_failure_order(__order));
>>       }
>>
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      wait(_Fp __old, memory_order __m = memory_order_seq_cst) const noexcept
>>+      { __atomic_impl::wait(&_M_fp, __old, __m); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_one() const noexcept
>>+      { __atomic_impl::notify_one(&_M_fp); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_all() const noexcept
>>+      { __atomic_impl::notify_all(&_M_fp); }
>>+
>>+      // TODO add const volatile overload
>>+
>>       value_type
>>       fetch_add(value_type __i,
>> 		memory_order __m = memory_order_seq_cst) noexcept
>>@@ -1323,6 +1444,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> 				       __cmpexch_failure_order(__order));
>>       }
>>
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
>>+      { __atomic_impl::wait(_M_ptr, __old, __m); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_one() const noexcept
>>+      { __atomic_impl::notify_one(_M_ptr); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_all() const noexcept
>>+      { __atomic_impl::notify_all(_M_ptr); }
>>+
>>+      // TODO add const volatile overload
>>+
>>     private:
>>       _Tp* _M_ptr;
>>     };
>>@@ -1418,6 +1557,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> 				       __cmpexch_failure_order(__order));
>>       }
>>
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
>>+      { __atomic_impl::wait(_M_ptr, __old, __m); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_one() const noexcept
>>+      { __atomic_impl::notify_one(_M_ptr); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_all() const noexcept
>>+      { __atomic_impl::notify_all(_M_ptr); }
>>+
>>+      // TODO add const volatile overload
>>+
>>       value_type
>>       fetch_add(value_type __i,
>> 		memory_order __m = memory_order_seq_cst) const noexcept
>>@@ -1573,6 +1730,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> 				       __cmpexch_failure_order(__order));
>>       }
>>
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      wait(_Fp __old, memory_order __m = memory_order_seq_cst) const noexcept
>>+      { __atomic_impl::wait(_M_ptr, __old, __m); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_one() const noexcept
>>+      { __atomic_impl::notify_one(_M_ptr); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_all() const noexcept
>>+      { __atomic_impl::notify_all(_M_ptr); }
>>+
>>+      // TODO add const volatile overload
>>+
>>       value_type
>>       fetch_add(value_type __i,
>> 		memory_order __m = memory_order_seq_cst) const noexcept
>>@@ -1682,6 +1857,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> 				       __cmpexch_failure_order(__order));
>>       }
>>
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      wait(_Tp __old, memory_order __m = memory_order_seq_cst) const noexcept
>>+      { __atomic_impl::wait(_M_ptr, __old, __m); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_one() const noexcept
>>+      { __atomic_impl::notify_one(_M_ptr); }
>>+
>>+      // TODO add const volatile overload
>>+
>>+      _GLIBCXX_ALWAYS_INLINE void
>>+      notify_all() const noexcept
>>+      { __atomic_impl::notify_all(_M_ptr); }
>>+
>>+      // TODO add const volatile overload
>>+
>>       _GLIBCXX_ALWAYS_INLINE value_type
>>       fetch_add(difference_type __d,
>> 		memory_order __m = memory_order_seq_cst) const noexcept
>>diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h b/libstdc++-v3/include/bits/atomic_timed_wait.h
>>new file mode 100644
>>index 00000000000..2f57356b366
>>--- /dev/null
>>+++ b/libstdc++-v3/include/bits/atomic_timed_wait.h
>>@@ -0,0 +1,281 @@
>>+// -*- C++ -*- header.
>>+
>>+// Copyright (C) 2020 Free Software Foundation, Inc.
>>+//
>>+// This file is part of the GNU ISO C++ Library.  This library is free
>>+// software; you can redistribute it and/or modify it under the
>>+// terms of the GNU General Public License as published by the
>>+// Free Software Foundation; either version 3, or (at your option)
>>+// any later version.
>>+
>>+// This library is distributed in the hope that it will be useful,
>>+// but WITHOUT ANY WARRANTY; without even the implied warranty of
>>+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>+// GNU General Public License for more details.
>>+
>>+// Under Section 7 of GPL version 3, you are granted additional
>>+// permissions described in the GCC Runtime Library Exception, version
>>+// 3.1, as published by the Free Software Foundation.
>>+
>>+// You should have received a copy of the GNU General Public License and
>>+// a copy of the GCC Runtime Library Exception along with this program;
>>+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>>+// <http://www.gnu.org/licenses/>.
>>+
>>+/** @file bits/atomic_timed_wait.h
>>+ *  This is an internal header file, included by other library headers.
>>+ *  Do not attempt to use it directly. @headername{atomic}
>>+ */
>>+
>>+#ifndef _GLIBCXX_ATOMIC_TIMED_WAIT_H
>>+#define _GLIBCXX_ATOMIC_TIMED_WAIT_H 1
>>+
>>+#pragma GCC system_header
>>+
>>+#include <bits/c++config.h>
>>+#include <bits/functional_hash.h>
>>+#include <bits/atomic_wait.h>
>>+
>>+#include <chrono>
>>+
>>+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
>>+#include <sys/time.h>
>>+#endif
>>+
>>+namespace std _GLIBCXX_VISIBILITY(default)
>>+{
>>+_GLIBCXX_BEGIN_NAMESPACE_VERSION
>>+
>>+  enum class __atomic_wait_status { no_timeout, timeout };
>>+
>>+  namespace __detail
>>+  {
>>+#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
>>+    using __platform_wait_clock_t = chrono::steady_clock;
>>+
>>+    template<typename _Duration>
>>+      __atomic_wait_status
>>+      __platform_wait_until_impl(__platform_wait_t* __addr,
>>+				 __platform_wait_t __val,
>>+				 const chrono::time_point<__platform_wait_clock_t,
>>+							  _Duration>& __atime) noexcept
>>+      {
>>+	auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
>>+	auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
>>+
>>+	struct timespec __rt =
>>+	{
>>+	  static_cast<std::time_t>(__s.time_since_epoch().count()),
>>+	  static_cast<long>(__ns.count())
>>+	};
>>+
>>+	auto __e = syscall (SYS_futex, __addr,
>>+			      static_cast<int>(__futex_wait_flags::__wait_bitset_private),
>>+			      __val, &__rt, nullptr,
>>+			      static_cast<int>(__futex_wait_flags::__bitset_match_any));
>>+	if (__e && !(errno == EINTR || errno == EAGAIN || errno == ETIMEDOUT))
>>+	    std::terminate();
>>+	return (__platform_wait_clock_t::now() < __atime)
>>+	       ? __atomic_wait_status::no_timeout : __atomic_wait_status::timeout;
>>+      }
>>+
>>+    template<typename _Clock, typename _Duration>
>>+      __atomic_wait_status
>>+      __platform_wait_until(__platform_wait_t* __addr, __platform_wait_t __val,
>>+			    const chrono::time_point<_Clock, _Duration>& __atime)
>>+      {
>>+	if constexpr (is_same_v<__platform_wait_clock_t, _Clock>)
>
> This case is impossible, since the other overload would be selected
> if the clock is the __platform_wait_clock_t (unless the caller says
> __platform_wait_until<__platform_wait_until> to explicitly call this
> overload, but users can't call this function, and we won't do that).
>

Which overload?

>>+	  {
>>+	    return std::__detail::__platform_wait_until_impl(__addr, __val, __atime);
>>+	  }



More information about the Gcc-patches mailing list