From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8982 invoked by alias); 9 Feb 2012 23:24:53 -0000 Received: (qmail 8959 invoked by uid 22791); 9 Feb 2012 23:24:46 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_CX,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 09 Feb 2012 23:24:14 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q19NOELN008559 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 9 Feb 2012 18:24:14 -0500 Received: from shotwell (ovpn-113-72.phx2.redhat.com [10.3.113.72]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q19NO8gI023035 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Thu, 9 Feb 2012 18:24:13 -0500 Date: Thu, 09 Feb 2012 23:47:00 -0000 From: Benjamin Kosnik To: gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org, jakub@redhat.com Subject: [v3] libstdc++/51798 Message-ID: <20120209152408.7592e6e7@shotwell> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="MP_/SLEkFvgb7Wsf=3O=bDa=KWt" Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2012-02/txt/msg00466.txt.bz2 --MP_/SLEkFvgb7Wsf=3O=bDa=KWt Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 256 This is the rest of 51798, completing the conversion to C++11 atomics in libstdc++. This is now a complete transition, modulo documentation which I plan to finish as a separate patch once I am back from the ISO C++ meeting. tested x86_64/linux -benjamin --MP_/SLEkFvgb7Wsf=3O=bDa=KWt Content-Type: text/x-patch Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=20120209-2.patch Content-length: 30016 2012-02-09 Benjamin Kosnik Jonathan Wakely PR libstdc++/51798 continued. * acinclude.m4 (GLIBCXX_ENABLE_ATOMIC_BUILTINS): Use __atomic_* builtins instead of __sync_* builtins for atomic functionality. * include/bits/shared_ptr_base.h: Same. * include/parallel/compatibility.h: Same. * include/profile/impl/profiler_state.h: Same. * include/tr1/shared_ptr.h: Same. * libsupc++/eh_ptr.cc: Same. * libsupc++/eh_throw.cc: Same. * libsupc++/eh_tm.cc: Same. * libsupc++/guard.cc: Same. * configure: Regenerated. * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line numbers. * testsuite/tr1/2_general_utilities/shared_ptr/cons/43820_neg.cc: Same. diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 529532e..e089b20 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -2685,7 +2685,7 @@ AC_DEFUN([GLIBCXX_ENABLE_PCH], [ dnl dnl Check for atomic builtins. dnl See: -dnl http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html#Atomic-Builtins +dnl http://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html dnl dnl This checks to see if the host supports the compiler-generated dnl builtins for atomic operations for various integral sizes. Note, this @@ -2726,12 +2726,13 @@ AC_DEFUN([GLIBCXX_ENABLE_ATOMIC_BUILTINS], [ [typedef bool atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize();], + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + ], [glibcxx_cv_atomic_bool=yes], [glibcxx_cv_atomic_bool=no]) ]) @@ -2744,12 +2745,13 @@ AC_DEFUN([GLIBCXX_ENABLE_ATOMIC_BUILTINS], [ [typedef short atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize();], + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + ], [glibcxx_cv_atomic_short=yes], [glibcxx_cv_atomic_short=no]) ]) @@ -2762,12 +2764,13 @@ AC_DEFUN([GLIBCXX_ENABLE_ATOMIC_BUILTINS], [ [typedef int atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize();], + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + ], [glibcxx_cv_atomic_int=yes], [glibcxx_cv_atomic_int=no]) ]) @@ -2780,12 +2783,13 @@ AC_DEFUN([GLIBCXX_ENABLE_ATOMIC_BUILTINS], [ [typedef long long atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize();], + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + ], [glibcxx_cv_atomic_long_long=yes], [glibcxx_cv_atomic_long_long=no]) ]) @@ -2807,12 +2811,13 @@ int main() typedef bool atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + return 0; } EOF @@ -2835,12 +2840,13 @@ int main() typedef short atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + return 0; } EOF @@ -2864,12 +2870,13 @@ int main() typedef int atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + return 0; } EOF @@ -2892,12 +2899,13 @@ int main() typedef long long atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + return 0; } EOF @@ -2918,8 +2926,11 @@ EOF CXXFLAGS="$old_CXXFLAGS" AC_LANG_RESTORE - # Set atomicity_dir to builtins if either of above tests pass. - if test $glibcxx_cv_atomic_int = yes || test $glibcxx_cv_atomic_bool = yes ; then + # Set atomicity_dir to builtins if all of above tests pass. + if test $glibcxx_cv_atomic_bool = yes \ + && test $glibcxx_cv_atomic_short = yes \ + && test $glibcxx_cv_atomic_int = yes \ + && test $glibcxx_cv_atomic_long_long = yes ; then AC_DEFINE(_GLIBCXX_ATOMIC_BUILTINS, 1, [Define if the compiler supports C++11 atomics.]) atomicity_dir=cpu/generic/atomicity_builtins diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 5c1c4bb..de4a630 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -15125,12 +15125,13 @@ main () typedef bool atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + ; return 0; } @@ -15166,12 +15167,13 @@ main () typedef short atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + ; return 0; } @@ -15207,12 +15209,13 @@ main () typedef int atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + ; return 0; } @@ -15248,12 +15251,13 @@ main () typedef long long atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + ; return 0; } @@ -15281,18 +15285,19 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; } # Fake what AC_TRY_COMPILE does. cat > conftest.$ac_ext << EOF -#line 15284 "configure" +#line 15288 "configure" int main() { typedef bool atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + return 0; } EOF @@ -15315,18 +15320,19 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15318 "configure" +#line 15323 "configure" int main() { typedef short atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + return 0; } EOF @@ -15349,19 +15355,20 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15352 "configure" +#line 15358 "configure" int main() { // NB: _Atomic_word not necessarily int. typedef int atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + return 0; } EOF @@ -15384,18 +15391,19 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15387 "configure" +#line 15394 "configure" int main() { typedef long long atomic_type; atomic_type c1; atomic_type c2; - const atomic_type c3(0); - __sync_fetch_and_add(&c1, c2); - __sync_val_compare_and_swap(&c1, c3, c2); - __sync_lock_test_and_set(&c1, c3); - __sync_lock_release(&c1); - __sync_synchronize(); + atomic_type c3(0); + __atomic_fetch_add(&c1, c2, __ATOMIC_RELAXED); + __atomic_compare_exchange_n(&c1, &c2, c3, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + __atomic_test_and_set(&c1, __ATOMIC_RELAXED); + __atomic_load_n(&c1, __ATOMIC_RELAXED); + return 0; } EOF @@ -15427,8 +15435,11 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu - # Set atomicity_dir to builtins if either of above tests pass. - if test $glibcxx_cv_atomic_int = yes || test $glibcxx_cv_atomic_bool = yes ; then + # Set atomicity_dir to builtins if all of above tests pass. + if test $glibcxx_cv_atomic_bool = yes \ + && test $glibcxx_cv_atomic_short = yes \ + && test $glibcxx_cv_atomic_int = yes \ + && test $glibcxx_cv_atomic_long_long = yes ; then $as_echo "#define _GLIBCXX_ATOMIC_BUILTINS 1" >>confdefs.h @@ -15460,7 +15471,7 @@ $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15463 "configure" +#line 15474 "configure" int main() { _Decimal32 d1; @@ -15502,7 +15513,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # unnecessary for this test. cat > conftest.$ac_ext << EOF -#line 15505 "configure" +#line 15516 "configure" template struct same { typedef T2 type; }; @@ -15536,7 +15547,7 @@ $as_echo "$enable_int128" >&6; } rm -f conftest* cat > conftest.$ac_ext << EOF -#line 15539 "configure" +#line 15550 "configure" template struct same { typedef T2 type; }; diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index c024b70..ebdc7ed 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -1,6 +1,7 @@ // shared_ptr and weak_ptr implementation details -*- C++ -*- -// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 +// 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 @@ -193,7 +194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // No memory barrier is used here so there is no synchronization // with other threads. - return const_cast(_M_use_count); + return __atomic_load_n(&_M_use_count, __ATOMIC_RELAXED); } private: @@ -245,8 +246,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Replace the current counter value with the old value + 1, as // long as it's not changed meanwhile. } - while (!__sync_bool_compare_and_swap(&_M_use_count, __count, - __count + 1)); + while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, + true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED)); } diff --git a/libstdc++-v3/include/parallel/compatibility.h b/libstdc++-v3/include/parallel/compatibility.h index 9fffd8e..460345e 100644 --- a/libstdc++-v3/include/parallel/compatibility.h +++ b/libstdc++-v3/include/parallel/compatibility.h @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008, 2009, 2010, 2012 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 @@ -102,7 +102,7 @@ namespace __gnu_parallel return _InterlockedExchangeAdd(reinterpret_cast(__ptr), __addend); #elif defined(__GNUC__) - return __sync_fetch_and_add(__ptr, __addend); + return __atomic_fetch_add(__ptr, __addend, __ATOMIC_ACQ_REL); #elif defined(__SUNPRO_CC) && defined(__sparc) volatile int32_t __before, __after; do @@ -145,11 +145,11 @@ namespace __gnu_parallel return _InterlockedExchangeAdd64(__ptr, __addend); #endif #elif defined(__GNUC__) && defined(__x86_64) - return __sync_fetch_and_add(__ptr, __addend); + return __atomic_fetch_add(__ptr, __addend, __ATOMIC_ACQ_REL); #elif defined(__GNUC__) && defined(__i386) && \ (defined(__i686) || defined(__pentium4) || defined(__athlon) \ || defined(__k8) || defined(__core2)) - return __sync_fetch_and_add(__ptr, __addend); + return __atomic_fetch_add(__ptr, __addend, __ATOMIC_ACQ_REL); #elif defined(__SUNPRO_CC) && defined(__sparc) volatile int64_t __before, __after; do @@ -252,7 +252,8 @@ namespace __gnu_parallel __replacement, __comparand) == __comparand; #elif defined(__GNUC__) - return __sync_bool_compare_and_swap(__ptr, __comparand, __replacement); + return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, true, + __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); #elif defined(__SUNPRO_CC) && defined(__sparc) return atomic_cas_32((volatile unsigned int*)__ptr, __comparand, __replacement) == __comparand; @@ -298,11 +299,13 @@ namespace __gnu_parallel #endif #elif defined(__GNUC__) && defined(__x86_64) - return __sync_bool_compare_and_swap(__ptr, __comparand, __replacement); + return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, true, + __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); #elif defined(__GNUC__) && defined(__i386) && \ (defined(__i686) || defined(__pentium4) || defined(__athlon) \ || defined(__k8) || defined(__core2)) - return __sync_bool_compare_and_swap(__ptr, __comparand, __replacement); + return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, true, + __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); #elif defined(__SUNPRO_CC) && defined(__sparc) return atomic_cas_64((volatile unsigned long long*)__ptr, __comparand, __replacement) == __comparand; diff --git a/libstdc++-v3/include/profile/impl/profiler_state.h b/libstdc++-v3/include/profile/impl/profiler_state.h index 111b97e..573aa0e 100644 --- a/libstdc++-v3/include/profile/impl/profiler_state.h +++ b/libstdc++-v3/include/profile/impl/profiler_state.h @@ -1,6 +1,6 @@ // -*- C++ -*- // -// Copyright (C) 2009, 2010 Free Software Foundation, Inc. +// Copyright (C) 2009, 2010, 2012 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 @@ -45,9 +45,12 @@ namespace __gnu_profile inline bool __turn(__state_type __s) - { return (_GLIBCXX_PROFILE_DATA(__state) - == __sync_val_compare_and_swap(&_GLIBCXX_PROFILE_DATA(__state), - __INVALID, __s)); } + { + __state_type inv(__INVALID); + return __atomic_compare_exchange_n(&_GLIBCXX_PROFILE_DATA(__state), + &inv, __s, true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); + } inline bool __turn_on() diff --git a/libstdc++-v3/include/tr1/shared_ptr.h b/libstdc++-v3/include/tr1/shared_ptr.h index c42084c..723e317 100644 --- a/libstdc++-v3/include/tr1/shared_ptr.h +++ b/libstdc++-v3/include/tr1/shared_ptr.h @@ -1,6 +1,7 @@ // -*- C++ -*- -// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 +// 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 @@ -246,9 +247,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // Replace the current counter value with the old value + 1, as // long as it's not changed meanwhile. } - while (!__sync_bool_compare_and_swap(&_M_use_count, __count, - __count + 1)); - } + while (!__atomic_compare_exchange_n(&_M_use_count, &__count, __count + 1, + true, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED)); + } template class _Sp_counted_base_impl diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc index 684580f..82ebb0b 100644 --- a/libstdc++-v3/libsupc++/eh_ptr.cc +++ b/libstdc++-v3/libsupc++/eh_ptr.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Implement the members of exception_ptr. -// Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -75,7 +75,7 @@ std::__exception_ptr::exception_ptr::_M_addref() _GLIBCXX_USE_NOEXCEPT { __cxa_refcounted_exception *eh = __get_refcounted_exception_header_from_obj (_M_exception_object); - __sync_add_and_fetch (&eh->referenceCount, 1); + __atomic_add_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL); } } @@ -87,7 +87,7 @@ std::__exception_ptr::exception_ptr::_M_release() _GLIBCXX_USE_NOEXCEPT { __cxa_refcounted_exception *eh = __get_refcounted_exception_header_from_obj (_M_exception_object); - if (__sync_sub_and_fetch (&eh->referenceCount, 1) == 0) + if (__atomic_sub_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) { if (eh->exc.exceptionDestructor) eh->exc.exceptionDestructor (_M_exception_object); @@ -191,7 +191,7 @@ __gxx_dependent_exception_cleanup(_Unwind_Reason_Code code, __cxa_free_dependent_exception (dep); - if (__sync_sub_and_fetch (&header->referenceCount, 1) == 0) + if (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) { if (header->exc.exceptionDestructor) header->exc.exceptionDestructor (header + 1); @@ -210,7 +210,7 @@ std::rethrow_exception(std::exception_ptr ep) __cxa_dependent_exception *dep = __cxa_allocate_dependent_exception (); dep->primaryException = obj; - __sync_add_and_fetch (&eh->referenceCount, 1); + __atomic_add_fetch (&eh->referenceCount, 1, __ATOMIC_ACQ_REL); dep->unexpectedHandler = __unexpected_handler; dep->terminateHandler = __terminate_handler; diff --git a/libstdc++-v3/libsupc++/eh_throw.cc b/libstdc++-v3/libsupc++/eh_throw.cc index a3d2b0d..de00602 100644 --- a/libstdc++-v3/libsupc++/eh_throw.cc +++ b/libstdc++-v3/libsupc++/eh_throw.cc @@ -1,6 +1,6 @@ // -*- C++ -*- Exception handling routines for throwing. // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, -// 2011 Free Software Foundation, Inc. +// 2011, 2012 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -44,7 +44,7 @@ __gxx_exception_cleanup (_Unwind_Reason_Code code, _Unwind_Exception *exc) __terminate (header->exc.terminateHandler); #if ATOMIC_INT_LOCK_FREE > 1 - if (__sync_sub_and_fetch (&header->referenceCount, 1) == 0) + if (__atomic_sub_fetch (&header->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) { #endif if (header->exc.exceptionDestructor) diff --git a/libstdc++-v3/libsupc++/eh_tm.cc b/libstdc++-v3/libsupc++/eh_tm.cc index 1df8644..bd9de6c 100644 --- a/libstdc++-v3/libsupc++/eh_tm.cc +++ b/libstdc++-v3/libsupc++/eh_tm.cc @@ -1,5 +1,5 @@ // -*- C++ -*- Exception handling routines for Transactional Memory. -// Copyright (C) 2009, 2011 Free Software Foundation, Inc. +// Copyright (C) 2009, 2011, 2012 Free Software Foundation, Inc. // // This file is part of GCC. // @@ -46,7 +46,7 @@ free_any_cxa_exception (_Unwind_Exception *eo) } #if __GCC_ATOMIC_INT_LOCK_FREE > 1 - if (__sync_sub_and_fetch (&h->referenceCount, 1) == 0) + if (__atomic_sub_fetch (&h->referenceCount, 1, __ATOMIC_ACQ_REL) == 0) #endif __cxa_free_exception (h + 1); } diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc index 643ecd7..b7b8d3f 100644 --- a/libstdc++-v3/libsupc++/guard.cc +++ b/libstdc++-v3/libsupc++/guard.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010, 2011 +// Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010, 2011, 2012 // Free Software Foundation, Inc. // // This file is part of GCC. @@ -239,34 +239,42 @@ namespace __cxxabiv1 return 0; # ifdef _GLIBCXX_USE_FUTEX - // If __sync_* and futex syscall are supported, don't use any global + // If __atomic_* and futex syscall are supported, don't use any global // mutex. if (__gthread_active_p ()) { int *gi = (int *) (void *) g; + int expected(0); const int guard_bit = _GLIBCXX_GUARD_BIT; const int pending_bit = _GLIBCXX_GUARD_PENDING_BIT; const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT; while (1) { - int old = __sync_val_compare_and_swap (gi, 0, pending_bit); - if (old == 0) - return 1; // This thread should do the initialization. - - if (old == guard_bit) - return 0; // Already initialized. - - if (old == pending_bit) + if (__atomic_compare_exchange_n(gi, &expected, pending_bit, true, + __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) { - int newv = old | waiting_bit; - if (__sync_val_compare_and_swap (gi, old, newv) != old) - continue; - - old = newv; + // This thread should do the initialization. + return 1; } - - syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAIT, old, 0); + + if (expected == guard_bit) + { + // Already initialized. + return 0; + } + if (expected == pending_bit) + { + int newv = expected | waiting_bit; + if (!__atomic_compare_exchange_n(gi, &expected, newv, true, + __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED)) + continue; + + expected = newv; + } + + syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAIT, expected, 0); } } # else @@ -316,13 +324,13 @@ namespace __cxxabiv1 void __cxa_guard_abort (__guard *g) throw () { #ifdef _GLIBCXX_USE_FUTEX - // If __sync_* and futex syscall are supported, don't use any global + // If __atomic_* and futex syscall are supported, don't use any global // mutex. if (__gthread_active_p ()) { int *gi = (int *) (void *) g; const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT; - int old = __sync_lock_test_and_set (gi, 0); + int old = __atomic_exchange_n (gi, 0, __ATOMIC_ACQ_REL); if ((old & waiting_bit) != 0) syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX); @@ -355,14 +363,14 @@ namespace __cxxabiv1 void __cxa_guard_release (__guard *g) throw () { #ifdef _GLIBCXX_USE_FUTEX - // If __sync_* and futex syscall are supported, don't use any global + // If __atomic_* and futex syscall are supported, don't use any global // mutex. if (__gthread_active_p ()) { int *gi = (int *) (void *) g; const int guard_bit = _GLIBCXX_GUARD_BIT; const int waiting_bit = _GLIBCXX_GUARD_WAITING_BIT; - int old = __sync_lock_test_and_set (gi, guard_bit); + int old = __atomic_exchange_n (gi, guard_bit, __ATOMIC_ACQ_REL); if ((old & waiting_bit) != 0) syscall (SYS_futex, gi, _GLIBCXX_FUTEX_WAKE, INT_MAX); diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc index 4276c40..0d51663 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc @@ -1,7 +1,7 @@ // { dg-options "-std=gnu++0x" } // { dg-do compile } -// Copyright (C) 2010, 2011 Free Software Foundation +// Copyright (C) 2010, 2011, 2012 Free Software Foundation // // 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 @@ -32,9 +32,9 @@ void test01() { X* px = 0; std::shared_ptr p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 771 } + // { dg-error "incomplete" "" { target *-*-* } 773 } std::shared_ptr p9(ap()); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 865 } + // { dg-error "incomplete" "" { target *-*-* } 867 } } diff --git a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/cons/43820_neg.cc index 0b86e8e..ae902dc 100644 --- a/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/cons/43820_neg.cc +++ b/libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/cons/43820_neg.cc @@ -30,9 +30,9 @@ void test01() { X* px = 0; std::tr1::shared_ptr p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 563 } + // { dg-error "incomplete" "" { target *-*-* } 565 } std::tr1::shared_ptr p9(ap()); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 602 } + // { dg-error "incomplete" "" { target *-*-* } 604 } } --MP_/SLEkFvgb7Wsf=3O=bDa=KWt--