From patchwork Wed Sep 26 16:17:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 975252 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-486475-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ZA+LyKIl"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42L34m3fV2z9s2P for ; Thu, 27 Sep 2018 02:17:43 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=WIgaBqIbkN6AmEKB4zU42tCryQagY1ByAFEyWCo2Wh6w/gQkH5Hb4 D01jts1ZS3UjeiXfWF0f3ENHCyKm392Qs1kFwe1GLqvDeKY4LOqTaZ2uDYLqnDY1 njmM9U0Uo4otuMlOkDllV9ORPpjwdp5VWzNi6MXDQEwedEpB6Sb4fk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=OVounH7R4U03NQqgkvWvpYO005g=; b=ZA+LyKIlLthEiQwo7U1F k5efqe3P/Tyf1/UuSUVnqWWHvajQ0KxmV++t+CML+UkVXqBUeWAv4Eviu6lNHC8o wsm9YuRnF7OFk/itLCV31Wqfe9OZlQ31Lb7BIrfpwkQO4LBeTOEfXdq3fU2bgm7I kNl2Z8FXBWV1+KhMPeT6Lz4= Received: (qmail 100562 invoked by alias); 26 Sep 2018 16:17:27 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 100527 invoked by uid 89); 26 Sep 2018 16:17:26 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=UD:name, greatly X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 26 Sep 2018 16:17:25 +0000 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C738386677; Wed, 26 Sep 2018 16:17:23 +0000 (UTC) Received: from localhost (unknown [10.33.36.94]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6CFAC308BE75; Wed, 26 Sep 2018 16:17:23 +0000 (UTC) Date: Wed, 26 Sep 2018 17:17:22 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] PR libstdc++/59439 optimize uses of classic ("C") std::locale Message-ID: <20180926161722.GA31395@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.9.2 (2017-12-15) The global locale::_Impl that represents the "C" locale is never destroyed, so there is no need to keep track of reference count updates for that object. This greatly reduce contention between threads that refer to the classic locale. Since the global std::locale initially uses the classic locale, this benefits the common case for any code using the global locale, such as construction/destruction of iostream objects. All these updates are done inside libstdc++.so so there's no need to worry about users' objects having inlined old versions of the code which still update the reference count for the classic locale. PR libstdc++/59439 * src/c++98/locale.cc (locale::locale(const locale&)): Bypass reference count updates for the classic locale. (locale::~locale()): Likewise. (locale::operator=(const locale&)): Likewise. * src/c++98/locale_init.cc (locale::locale()): Likewise. (locale::global(const locale&)): Likewise. Tested x86_64-linux, not committed yet. Does anybody see any problems with this change? commit 131d4c26876a5a884fe4408deaf054e01ba90ffb Author: Jonathan Wakely Date: Wed Sep 26 16:34:42 2018 +0100 PR libstdc++/59439 optimize uses of classic ("C") std::locale The global locale::_Impl that represents the "C" locale is never destroyed, so there is no need to keep track of reference count updates for that object. This greatly reduce contention between threads that refer to the classic locale. Since the global std::locale initially uses the classic locale, this benefits the common case for any code using the global locale, such as construction/destruction of iostream objects. All these updates are done inside libstdc++.so so there's no need to worry about users' objects having inlined old versions of the code which still update the reference count for the classic locale. PR libstdc++/59439 * src/c++98/locale.cc (locale::locale(const locale&)): Bypass reference count updates for the classic locale. (locale::~locale()): Likewise. (locale::operator=(const locale&)): Likewise. * src/c++98/locale_init.cc (locale::locale()): Likewise. (locale::global(const locale&)): Likewise. diff --git a/libstdc++-v3/src/c++98/locale.cc b/libstdc++-v3/src/c++98/locale.cc index 148bf59658e..fe06d297039 100644 --- a/libstdc++-v3/src/c++98/locale.cc +++ b/libstdc++-v3/src/c++98/locale.cc @@ -77,7 +77,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION locale::locale(const locale& __other) throw() : _M_impl(__other._M_impl) - { _M_impl->_M_add_reference(); } + { + if (_M_impl != _S_classic) + _M_impl->_M_add_reference(); + } // This is used to initialize global and classic locales, and // assumes that the _Impl objects are constructed correctly. @@ -86,7 +89,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { } locale::~locale() throw() - { _M_impl->_M_remove_reference(); } + { + if (_M_impl != _S_classic) + _M_impl->_M_remove_reference(); + } bool locale::operator==(const locale& __rhs) const throw() @@ -112,8 +118,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const locale& locale::operator=(const locale& __other) throw() { - __other._M_impl->_M_add_reference(); - _M_impl->_M_remove_reference(); + if (__other._M_impl != _S_classic) + __other._M_impl->_M_add_reference(); + if (_M_impl != _S_classic) + _M_impl->_M_remove_reference(); _M_impl = __other._M_impl; return *this; } diff --git a/libstdc++-v3/src/c++98/locale_init.cc b/libstdc++-v3/src/c++98/locale_init.cc index c9078c015c3..b580a9f9d58 100644 --- a/libstdc++-v3/src/c++98/locale_init.cc +++ b/libstdc++-v3/src/c++98/locale_init.cc @@ -257,9 +257,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // fall back to lock protected access to both _S_global and // its reference count. _M_impl = _S_global; - if (_M_impl == _S_classic) - _M_impl->_M_add_reference(); - else + if (_M_impl != _S_classic) { __gnu_cxx::__scoped_lock sentry(get_locale_mutex()); _S_global->_M_add_reference(); @@ -275,7 +273,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __gnu_cxx::__scoped_lock sentry(get_locale_mutex()); __old = _S_global; - __other._M_impl->_M_add_reference(); + if (__other._M_impl != _S_classic) + __other._M_impl->_M_add_reference(); _S_global = __other._M_impl; const string __other_name = __other.name(); if (__other_name != "*") @@ -284,7 +283,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Reference count sanity check: one reference removed for the // subsition of __other locale, one added by return-by-value. Net - // difference: zero. When the returned locale object's destrutor + // difference: zero. When the returned locale object's destructor // is called, then the reference count is decremented and possibly // destroyed. return locale(__old);