From patchwork Fri Oct 24 14:14:28 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 402889 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 6CD61140077 for ; Sat, 25 Oct 2014 01:14:44 +1100 (AEDT) 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:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=etyj+/to1EbdXZkFL15umCm6Ng9meATIgxKqAEEw4aQoBbgBLW VA/xoBXhdt+wkWIhPfGkHRjJMQlsz/FDePR822SCy8DTJOJA1CaUOTNCZwyuv/GU j3fIsE3q7QDepELM6IdMnLJi6vcT0yB3+CMZxKcYyH3toOK9WxN98UkKk= 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:cc:subject:message-id:mime-version:content-type; s= default; bh=mru7PfKIlmt+xVul1aVqs3NDOtk=; b=s+E3BcWFqbJ3BEyoZ4Mh EGG5d1tYTrRYlCNNEN9QZjY+qjDNuo0i8qqUMHWEqsRv6D8bO6QePgX8pv4XpnGS cXgt2+ynGFgsA8c+L1s2+w1e+C20N7Lx8haOTPW3NjtZqT+XZCbrkk3UbPTmKTt2 UWG30CDYzeLzTlikj7mwbLg= Received: (qmail 23140 invoked by alias); 24 Oct 2014 14:14:37 -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 23122 invoked by uid 89); 24 Oct 2014 14:14:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.8 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients 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 (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 24 Oct 2014 14:14:35 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s9OEEVCM016122 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 24 Oct 2014 10:14:32 -0400 Received: from localhost (ovpn-116-123.ams2.redhat.com [10.36.116.123]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s9OEETsp021014; Fri, 24 Oct 2014 10:14:30 -0400 Date: Fri, 24 Oct 2014 15:14:28 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: triegel@redhat.com Subject: Unifying std::atomic_int and std::atomic Message-ID: <20141024141428.GD3033@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) Our was implemented (by Benjamin IIRC) based on an early C++0x draft when the spec was still trying to be valid for both C and C++. Part of the C compatibility aspect was that std::atomic_int is allowed to be either a typedef for std::atomic or a base class of it, so that a C library could define std::atomic_int and then the C++ library could make std::atomic derive from that. In the final C11 spec atomics work completely differently, and atomic_int is a typedef for _Atomic int, which is not a valid base class. So the old C++0x draft's compatibility aim is impossible, atomic_int can never be the same type in C and C++. In our implementation, std::atomic_int is a base class of std::atomic, which has no benefit I can see, but causes https://gcc.gnu.org/PR60940 Rather than overloading every atomic_op() non-member function to handle the derived class and the base class, it would be simpler to just get rid of the base classes and make atomic_xxx a typedef for atomic, as the attached patch does for atomic_{bool,char,schar}. Does anyone object to that change? If you object, are you prepared to do the work to fix PR60940? :-) [Note:- it could probably be simplified even further so atomic is just: template<> struct atomic : public __atomic_base { using __atomic_base::__atomic_base; }; But that could be done later as it wouldn't change anything observable, making atomic_char a typedef for atomic is the observable and IMHO important change. -end note] diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h index 1fc0ebb..a591c46 100644 --- a/libstdc++-v3/include/bits/atomic_base.h +++ b/libstdc++-v3/include/bits/atomic_base.h @@ -120,12 +120,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template struct __atomic_base; - /// atomic_char - typedef __atomic_base atomic_char; - - /// atomic_schar - typedef __atomic_base atomic_schar; - /// atomic_uchar typedef __atomic_base atomic_uchar; diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic index 85dc252..c58853e 100644 --- a/libstdc++-v3/include/std/atomic +++ b/libstdc++-v3/include/std/atomic @@ -49,21 +49,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ - /// atomic_bool + template + struct atomic; + + /// atomic // NB: No operators or fetch-operations for this type. - struct atomic_bool + template<> + struct atomic { private: __atomic_base _M_base; public: - atomic_bool() noexcept = default; - ~atomic_bool() noexcept = default; - atomic_bool(const atomic_bool&) = delete; - atomic_bool& operator=(const atomic_bool&) = delete; - atomic_bool& operator=(const atomic_bool&) volatile = delete; + atomic() noexcept = default; + ~atomic() noexcept = default; + atomic(const atomic&) = delete; + atomic& operator=(const atomic&) = delete; + atomic& operator=(const atomic&) volatile = delete; - constexpr atomic_bool(bool __i) noexcept : _M_base(__i) { } + constexpr atomic(bool __i) noexcept : _M_base(__i) { } bool operator=(bool __i) noexcept @@ -151,6 +155,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return _M_base.compare_exchange_strong(__i1, __i2, __m); } }; + /// atomic_bool + typedef atomic atomic_bool; + /** * @brief Generic atomic type, primary class template. @@ -485,31 +492,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; - /// Explicit specialization for bool. - template<> - struct atomic : public atomic_bool - { - typedef bool __integral_type; - typedef atomic_bool __base_type; - - atomic() noexcept = default; - ~atomic() noexcept = default; - atomic(const atomic&) = delete; - atomic& operator=(const atomic&) = delete; - atomic& operator=(const atomic&) volatile = delete; - - constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { } - - using __base_type::operator __integral_type; - using __base_type::operator=; - }; - /// Explicit specialization for char. template<> - struct atomic : public atomic_char + struct atomic : public __atomic_base { typedef char __integral_type; - typedef atomic_char __base_type; + typedef __atomic_base __base_type; atomic() noexcept = default; ~atomic() noexcept = default; @@ -523,12 +511,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __base_type::operator=; }; + /// atomic_char + typedef atomic atomic_char; + /// Explicit specialization for signed char. template<> - struct atomic : public atomic_schar + struct atomic : public __atomic_base { typedef signed char __integral_type; - typedef atomic_schar __base_type; + typedef __atomic_base __base_type; atomic() noexcept= default; ~atomic() noexcept = default; @@ -542,6 +533,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __base_type::operator=; }; + /// atomic_schar + typedef atomic atomic_schar; + /// Explicit specialization for unsigned char. template<> struct atomic : public atomic_uchar