Jonathan Wakely writes:
> On 11/09/20 16:58 -0700, Thomas Rodgers wrote: >>From: Thomas Rodgers <trodg...@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); >>+ }