From patchwork Thu Nov 16 13:45:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 165853 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b909:0:b0:403:3b70:6f57 with SMTP id t9csp3284322vqg; Thu, 16 Nov 2023 07:23:20 -0800 (PST) X-Google-Smtp-Source: AGHT+IHaxRmC1MG+EEU26L9K+4aN1XqXzva2KoQ9t6ed80Gpvxf206wm7pEhEHtjGDwOch9ewP9L X-Received: by 2002:ac8:5f84:0:b0:41c:e17e:1448 with SMTP id j4-20020ac85f84000000b0041ce17e1448mr9581508qta.36.1700148199965; Thu, 16 Nov 2023 07:23:19 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1700148199; cv=pass; d=google.com; s=arc-20160816; b=gutUh3w4bR6P9wxx1ay982Ypd9G76+0AMLktcB7EpOBAyWRBnNgq3EnDVU80kDNzEg EhhwFrOkTmrnA7izZ3W+MVKeYggwSjruUpV3tf9mcvtH2MKl6+3F3U5ZwxwZ/ZWb4O8r /aeYMpaXJfRFR/kDoRfcZGsP69ev5iMjGpQbKaCHCdQMa7nHH2D7u6eh2XEidpOmqoSU OD6OZJ5Eckw+SgBKmmUptjNikk7fzEW6AguEbTlHUi/EcV+S0AqjD/fV+vkEJEInu0Pi Ob74SF2YTmAo80EXUXQTF3OuLvIN99581vY12Q90CH5278qYS2OMudoNOvyidGw8myx6 QKMw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=GUZ+hUaBuKtUtX8oQKgRSmM96v7PtkscJao0ygm1+JU=; fh=g67BvFYICNGk2M5XbPVbHseNOCKPNA0HKvqCGpeHR/Q=; b=zaVozhVasRe3H7FLCdqe2meC/CTtsRIE7rYyGxcdUQmJKs8LpjdBW4KLq/x2HDv1/k k3Qd6xbGJhh9y4zgjPTFFF1NGfv50ZqHg32tJOqr8I23j/P/szK0WQJLLyCFlKUBG/jl 2QbI92x9UtgQ73IdUv0S7khDOJ3CePpIHnuMgdksx8wAnrdI3RGuSydktZ6olpD24SYJ x4Cci17q60tvbRIlaZToZgwqvHxBWCL+FhC8MIuX6CT9VsnE3W0KCtDrgxYFBahnHUi/ aNdiQir0v39ZgsQAjbBXHG6w+xUdutGXJbQLJT3+W6D9i0ZGXPcGhXCDLgZZeOh2jvYg MY5g== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=RWvNqldC; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id q10-20020a05622a04ca00b0040eb9b330d5si11381523qtx.492.2023.11.16.07.23.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Nov 2023 07:23:19 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=RWvNqldC; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 35C5B3858287 for ; Thu, 16 Nov 2023 13:48:09 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 2DD283858CD1 for ; Thu, 16 Nov 2023 13:47:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2DD283858CD1 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2DD283858CD1 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700142465; cv=none; b=vgTLfLxgW+C0P26NpgWgvBduVRKdnLS/7csmBtugJU5LIgU5BUUkZ7ySBY4mY8/U71SPWwFEXAeFzjucOFptHB+pBr17F41wB/DG66uGbRoGJ37ISXiKCkcfUEX8co4RFgbIezt61Eqr55C5Xfpq1HqTZ7WOKe9JCXXjKPuLUkM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700142465; c=relaxed/simple; bh=jyZYNP87fXV0usXlYQv5wSb/fgDxt3A8q9qiqSntQt0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=sjAvcslRQ2wdmWeDwJqiYgv7AlIl0G4x0Iek2JFDiFsLm5cLZZwzJRiCS2RMwC5ijbM+KcBfixZ9jHcoYksIrHwUBJb2yGTu/vS6yoxxppUwM5OyD4mtzkpytEuVrj76ynKFHqjA557WABDegYnfMOsb2gVNE/CT0ezrmGF8eDc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1700142462; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GUZ+hUaBuKtUtX8oQKgRSmM96v7PtkscJao0ygm1+JU=; b=RWvNqldC6CQP3V3panPD1Mnq3FChRvI1w+3dZE4VvxXBlh9kGot1AIzG1nfhILBAcpYweK 4YF23IBQJDTdqGSWb6euKvvGXy8OpzQshguQhM5xny9SIsaldWEuYFbCQn/GsGuUFXS8H7 9/LwDpdrUzrYRICyZTZSGNd+f+7yG0I= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-659-LhDIEyMiNi60hXlzxj58rw-1; Thu, 16 Nov 2023 08:47:39 -0500 X-MC-Unique: LhDIEyMiNi60hXlzxj58rw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 57FC69758C2; Thu, 16 Nov 2023 13:47:39 +0000 (UTC) Received: from localhost (unknown [10.42.28.9]) by smtp.corp.redhat.com (Postfix) with ESMTP id 00F6B40C6EBB; Thu, 16 Nov 2023 13:47:38 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: Thomas Rodgers , Thomas Rodgers Subject: [PATCH 2/2] libstdc++: Pass __wait_args to internal API by const pointer Date: Thu, 16 Nov 2023 13:45:38 +0000 Message-ID: <20231116134736.1287539-2-jwakely@redhat.com> In-Reply-To: <20231116134736.1287539-1-jwakely@redhat.com> References: <20231116134736.1287539-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.2 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.9 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_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782734598924321643 X-GMAIL-MSGID: 1782734598924321643 From: Thomas Rodgers Tested x86_64-linux, testing underway on powerpc-aix and sparc-solaris. -- >8 -- This change splits the __wait_args data members to a new struct __wait_args_base and then passes that type by const pointer to the low level implementation functions. libstdc++-v3/ChangeLog: * include/bits/atomic_timed_wait.h (__spin_until_impl): Accept __wait_args as const __wait_args_base*. (__wait_until_impl): Likewise. (__wait_until): Likewise. (__wait_for): Likewise. (__atomic_wait_address_until): Pass __wait_args by address. (__atomic_wait_address_for): Likewise. * include/bits/atomic_wait.h (__wait_args_base): New struct. (__wait_args): Derive from __wait_args_base. (__wait_args::__wait_args()): Adjust ctors to call call base ctor. (__wait_args::__wait_args(const __wait_args_base&)): New ctor. (__wait_args::operator|=): New method. (__wait_args::_S_flags_for): Change return type to __wait_flags. (__spin_impl): Accept __wait_args as const __wait_args_base*. (__wait_impl): Likewise. (__notify_impl): Likewise. (__atomic_wait_address): Pass __wait_args by address. (__atomic_wait_address_v): Likewise. (__atomic_notify_address): Likewise. --- libstdc++-v3/include/bits/atomic_timed_wait.h | 35 +++++++---- libstdc++-v3/include/bits/atomic_wait.h | 62 +++++++++++++------ 2 files changed, 64 insertions(+), 33 deletions(-) diff --git a/libstdc++-v3/include/bits/atomic_timed_wait.h b/libstdc++-v3/include/bits/atomic_timed_wait.h index 90427ef8b42..6f6e8758ee2 100644 --- a/libstdc++-v3/include/bits/atomic_timed_wait.h +++ b/libstdc++-v3/include/bits/atomic_timed_wait.h @@ -133,9 +133,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif // _GLIBCXX_HAS_GTHREADS inline __wait_result_type - __spin_until_impl(const __platform_wait_t* __addr, __wait_args __args, + __spin_until_impl(const __platform_wait_t* __addr, + const __wait_args_base* __a, const __wait_clock_t::time_point& __deadline) { + __wait_args __args{ *__a }; auto __t0 = __wait_clock_t::now(); using namespace literals::chrono_literals; @@ -161,7 +163,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } else { - auto __res = __detail::__spin_impl(__addr, __args); + auto __res = __detail::__spin_impl(__addr, __a); if (__res.first) return __res; } @@ -174,9 +176,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } inline __wait_result_type - __wait_until_impl(const __platform_wait_t* __addr, __wait_args __args, + __wait_until_impl(const __platform_wait_t* __addr, + const __wait_args_base* __a, const __wait_clock_t::time_point& __atime) { + __wait_args __args{ *__a }; #ifdef _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT __waiter_pool_impl* __pool = nullptr; #else @@ -198,7 +202,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__args & __wait_flags::__do_spin) { - auto __res = __detail::__spin_until_impl(__wait_addr, __args, __atime); + auto __res = __detail::__spin_until_impl(__wait_addr, __a, __atime); if (__res.first) return __res; if (__args & __wait_flags::__spin_only) @@ -244,7 +248,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template __wait_result_type - __wait_until(const __platform_wait_t* __addr, __wait_args __args, + __wait_until(const __platform_wait_t* __addr, const __wait_args* __args, const chrono::time_point<_Clock, _Dur>& __atime) noexcept { if constexpr (is_same_v<__wait_clock_t, _Clock>) @@ -267,15 +271,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template __wait_result_type - __wait_for(const __platform_wait_t* __addr, __wait_args __args, + __wait_for(const __platform_wait_t* __addr, const __wait_args_base* __a, const chrono::duration<_Rep, _Period>& __rtime) noexcept { + __wait_args __args{ *__a }; if (!__rtime.count()) - // no rtime supplied, just spin a bit - return __detail::__wait_impl(__addr, __args | __wait_flags::__spin_only); + { + // no rtime supplied, just spin a bit + __args |= __wait_flags::__spin_only; + return __detail::__wait_impl(__addr, &__args); + } + auto const __reltime = chrono::ceil<__wait_clock_t::duration>(__rtime); auto const __atime = chrono::steady_clock::now() + __reltime; - return __detail::__wait_until(__addr, __args, __atime); + return __detail::__wait_until(__addr, &__args, __atime); } } // namespace __detail @@ -295,7 +304,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tp __val = __vfn(); while (!__pred(__val)) { - auto __res = __detail::__wait_until(__wait_addr, __args, __atime); + auto __res = __detail::__wait_until(__wait_addr, &__args, __atime); if (!__res.first) // timed out return __res.first; // C++26 will also return last observed __val @@ -313,7 +322,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool __bare_wait = false) noexcept { __detail::__wait_args __args{ __addr, __old, __order, __bare_wait }; - auto __res = __detail::__wait_until(__addr, __args, __atime); + auto __res = __detail::__wait_until(__addr, &__args, __atime); return __res.first; // C++26 will also return last observed __val } @@ -345,7 +354,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tp __val = __vfn(); while (!__pred(__val)) { - auto __res = __detail::__wait_for(__wait_addr, __args, __rtime); + auto __res = __detail::__wait_for(__wait_addr, &__args, __rtime); if (!__res.first) // timed out return __res.first; // C++26 will also return last observed __val @@ -363,7 +372,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool __bare_wait = false) noexcept { __detail::__wait_args __args{ __addr, __old, __order, __bare_wait }; - auto __res = __detail::__wait_for(__addr, __args, __rtime); + auto __res = __detail::__wait_for(__addr, &__args, __rtime); return __res.first; // C++26 will also return last observed __Val } diff --git a/libstdc++-v3/include/bits/atomic_wait.h b/libstdc++-v3/include/bits/atomic_wait.h index 63d132fc9a8..8abcdec3d50 100644 --- a/libstdc++-v3/include/bits/atomic_wait.h +++ b/libstdc++-v3/include/bits/atomic_wait.h @@ -212,23 +212,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __abi_version_mask = 0xffff0000, }; - struct __wait_args + struct __wait_args_base { - __platform_wait_t _M_old; - int _M_order = __ATOMIC_ACQUIRE; __wait_flags _M_flags; + int _M_order = __ATOMIC_ACQUIRE; + __platform_wait_t _M_old = 0; + }; + struct __wait_args : __wait_args_base + { template explicit __wait_args(const _Tp* __addr, bool __bare_wait = false) noexcept - : _M_flags{ _S_flags_for(__addr, __bare_wait) } + : __wait_args_base{ _S_flags_for(__addr, __bare_wait) } { } __wait_args(const __platform_wait_t* __addr, __platform_wait_t __old, int __order, bool __bare_wait = false) noexcept - : _M_old{ __old } - , _M_order{ __order } - , _M_flags{ _S_flags_for(__addr, __bare_wait) } + : __wait_args_base{ _S_flags_for(__addr, __bare_wait), __order, __old } + { } + + explicit __wait_args(const __wait_args_base& __base) + : __wait_args_base{ __base } { } __wait_args(const __wait_args&) noexcept = default; @@ -254,6 +259,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __res; } + __wait_args& + operator|=(__wait_flags __flag) noexcept + { + using __t = underlying_type_t<__wait_flags>; + const auto __flags = static_cast<__t>(_M_flags) + | static_cast<__t>(__flag); + _M_flags = __wait_flags{ __flags }; + return *this; + } + private: static int constexpr _S_default_flags() noexcept @@ -264,7 +279,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } template - static int + static __wait_flags constexpr _S_flags_for(const _Tp*, bool __bare_wait) noexcept { auto __res = _S_default_flags(); @@ -272,7 +287,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __res |= static_cast(__wait_flags::__track_contention); if constexpr (!__platform_wait_uses_type<_Tp>) __res |= static_cast(__wait_flags::__proxy_wait); - return __res; + return static_cast<__wait_flags>(__res); } template @@ -287,13 +302,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __wait_result_type = pair; inline __wait_result_type - __spin_impl(const __platform_wait_t* __addr, __wait_args __args) + __spin_impl(const __platform_wait_t* __addr, const __wait_args_base* __args) { __platform_wait_t __val; for (auto __i = 0; __i < __atomic_spin_count; ++__i) { - __atomic_load(__addr, &__val, __args._M_order); - if (__val != __args._M_old) + __atomic_load(__addr, &__val, __args->_M_order); + if (__val != __args->_M_old) return make_pair(true, __val); if (__i < __atomic_spin_count_relax) __detail::__thread_relax(); @@ -304,8 +319,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } inline __wait_result_type - __wait_impl(const __platform_wait_t* __addr, __wait_args __args) + __wait_impl(const __platform_wait_t* __addr, const __wait_args_base* __a) { + __wait_args __args{ *__a }; #ifdef _GLIBCXX_HAVE_PLATFORM_WAIT __waiter_pool_impl* __pool = nullptr; #else @@ -314,20 +330,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif __platform_wait_t* __wait_addr; + __platform_wait_t __old; if (__args & __wait_flags::__proxy_wait) { #ifdef _GLIBCXX_HAVE_PLATFORM_WAIT __pool = &__waiter_pool_impl::_S_impl_for(__addr); #endif __wait_addr = &__pool->_M_ver; - __atomic_load(__wait_addr, &__args._M_old, __args._M_order); + __atomic_load(__wait_addr, &__old, __args._M_order); } else - __wait_addr = const_cast<__platform_wait_t*>(__addr); + { + __wait_addr = const_cast<__platform_wait_t*>(__addr); + __old = __args._M_old; + } + if (__args & __wait_flags::__do_spin) { - auto __res = __detail::__spin_impl(__wait_addr, __args); + auto __res = __detail::__spin_impl(__wait_addr, __a); if (__res.first) return __res; if (__args & __wait_flags::__spin_only) @@ -369,8 +390,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline void __notify_impl(const __platform_wait_t* __addr, [[maybe_unused]] bool __all, - __wait_args __args) + const __wait_args_base* __a) { + __wait_args __args{ __a }; #ifdef _GLIBCXX_HAVE_PLATFORM_WAIT __waiter_pool_impl* __pool = nullptr; #else @@ -421,7 +443,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Tp __val = __vfn(); while (!__pred(__val)) { - __detail::__wait_impl(__wait_addr, __args); + __detail::__wait_impl(__wait_addr, &__args); __val = __vfn(); } // C++26 will return __val @@ -434,7 +456,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __detail::__wait_args __args{ __addr, __old, __order }; // C++26 will not ignore the return value here - __detail::__wait_impl(__addr, __args); + __detail::__wait_impl(__addr, &__args); } template @@ -455,7 +477,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const auto __wait_addr = reinterpret_cast(__addr); __detail::__wait_args __args{ __addr, __bare_wait }; - __detail::__notify_impl(__wait_addr, __all, __args); + __detail::__notify_impl(__wait_addr, __all, &__args); } _GLIBCXX_END_NAMESPACE_VERSION } // namespace std