From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id C52AB3858004 for ; Mon, 23 Nov 2020 18:30:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org C52AB3858004 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-58-tvlUTrouPBGoKi6DTEbnOg-1; Mon, 23 Nov 2020 13:30:47 -0500 X-MC-Unique: tvlUTrouPBGoKi6DTEbnOg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 47E4918C43C1; Mon, 23 Nov 2020 18:30:46 +0000 (UTC) Received: from localhost (unknown [10.33.37.15]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8D7B560C04; Mon, 23 Nov 2020 18:30:45 +0000 (UTC) Date: Mon, 23 Nov 2020 18:30:44 +0000 From: Jonathan Wakely To: Jonathan Wakely Cc: David Edelsohn , libstdc++ , GCC Patches Subject: Re: [PATCH] libstdc++: Add C++2a synchronization support Message-ID: <20201123183044.GW1312820@redhat.com> References: MIME-Version: 1.0 In-Reply-To: X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="hcut4fGOf7Kh6EdG" Content-Disposition: inline X-Spam-Status: No, score=-14.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libstdc++@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++ mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Nov 2020 18:30:53 -0000 --hcut4fGOf7Kh6EdG Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline On 22/11/20 01:27 +0000, Jonathan Wakely via Libstdc++ wrote: >On Sat, 21 Nov 2020 at 23:55, David Edelsohn via Libstdc++ > 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. --hcut4fGOf7Kh6EdG Content-Type: text/x-patch; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 183ae52b226898cc34aa51d4153cf0c006212a8a Author: Jonathan Wakely 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::wait, __atomic_base::notify_one) (__atomic_base::notify_all, __atomic_base::wait) (__atomic_base::notify_one, __atomic_base::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 _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 @@ -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 +#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX #include #include @@ -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 +#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX #include #include #include @@ -106,7 +107,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } - template + template 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 +#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX #include #include @@ -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 - struct __atomic_semaphore + template + struct __atomic_semaphore + { + static_assert(std::is_integral_v<_Tp>); + static_assert(__gnu_cxx::__int_traits<_Tp>::__max + <= __gnu_cxx::__int_traits::__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::__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 + _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 - _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 @@ -299,4 +300,5 @@ template _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 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 +#if defined _GLIBCXX_HAS_GTHREADS || _GLIBCXX_HAVE_LINUX_FUTEX #include namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +#define __cpp_lib_semaphore 201907L + template::__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 --hcut4fGOf7Kh6EdG--