diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b2972f19f566a6a0a3ec9d466d35f7dde22f5d86..af3f50af0eb331139bdb975c818e2908af81a379 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,21 @@ +2012-02-10 Benjamin Kosnik <bkoz@redhat.com> + Jonathan Wakely <jwakely.gcc@gmail.com> + + 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. + 2012-02-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> PR libstdc++/51296 diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 529532e52601369e426735d1571f1c0bf6558bc6..e089b20dd4f6d153c84a111d878883f501b07ab9 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 5c1c4bbe639788c7add585a47bee7aedc18c9aa6..de4a630e25ac0cbd146860aa7e07819f2675049e 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<typename T1, typename T2> 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<typename T1, typename T2> 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 c024b70fb5087a07f76986d7fb7251543142747b..ebdc7ed945258a838e30337e8f57a9eab02c3a70 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<const volatile _Atomic_word&>(_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 9fffd8e012ccc9e51697772878166f583f366d6a..460345ef3994551df029b10ed7b1d80d0062a744 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<volatile long*>(__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 111b97e0ecabed3ff152de152ad560f81bf24dd6..573aa0eeb403c0c781ec2d589447d38dca1d39f5 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 c42084c9539a49f2c9842803cadc16f3c968e2eb..723e317646de6f112dad28bca122c03470fde3ea 100644 --- a/libstdc++-v3/include/tr1/shared_ptr.h +++ b/libstdc++-v3/include/tr1/shared_ptr.h @@ -1,6 +1,7 @@ // <tr1/shared_ptr.h> -*- 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<typename _Ptr, typename _Deleter, _Lock_policy _Lp> class _Sp_counted_base_impl diff --git a/libstdc++-v3/libsupc++/eh_ptr.cc b/libstdc++-v3/libsupc++/eh_ptr.cc index 684580f413ee82051fb89cf90c5569b359ea2cb4..82ebb0b173baee8424e3cc898c52840cc171252e 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 a3d2b0d24b2f8340342fe84a10617011196d2e97..de00602cdea3c3f263c0de17af4ef57ce0e62822 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 1df8644ea0c0e5306b00f3d493a14b1339e4bb14..bd9de6c60e4982676355c445cb1566c5903a2532 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 643ecd703a16e6814e43b247bae521844d1697be..b7b8d3f855b80cbbfab5056365048c6c9c25e4aa 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 4276c406269ea7495131ef185c0d189eebc8d8b2..0d51663fb75c1e9d35f07015beec10c4b253f5c5 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<X> p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 771 } + // { dg-error "incomplete" "" { target *-*-* } 773 } std::shared_ptr<X> 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 0b86e8eeb922eb203daf5052a7e83a57028cd481..ae902dc775167c5c66fc0fa16a6a096cf12fa7a7 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<X> p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 563 } + // { dg-error "incomplete" "" { target *-*-* } 565 } std::tr1::shared_ptr<X> p9(ap()); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 602 } + // { dg-error "incomplete" "" { target *-*-* } 604 } }