diff options
author | Richard Henderson <rth@redhat.com> | 2012-02-13 13:30:31 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2012-02-13 13:30:31 -0800 |
commit | b2cb69647e04765b87f0f1ba9f39b4a353574135 (patch) | |
tree | 840fce549883497ba5e22c723942237b1faa64ab /libstdc++-v3 | |
parent | 67b977ada8b0fece1138d67d2ebfbf2e9b030d01 (diff) | |
download | gcc-b2cb69647e04765b87f0f1ba9f39b4a353574135.zip gcc-b2cb69647e04765b87f0f1ba9f39b4a353574135.tar.gz gcc-b2cb69647e04765b87f0f1ba9f39b4a353574135.tar.bz2 |
PR libstdc++/51798 continued
PR libstdc++/51798 continued
* include/bits/shared_ptr_base.h
(_Sp_counted_base<_S_atomic>::_M_add_ref_lock): Hoist initial load
outside compare_exchange loop.
* include/tr1/shared_ptr.h: Same.
* include/parallel/compatibility.h (__compare_and_swap_32): Use strong
version of compare_exchange.
(__compare_and_swap_64): Same.
* include/profile/impl/profiler_state.h (__gnu_profile::__turn): Same.
* libsupc++/guard.cc (__cxa_guard_acquire): Same.
From-SVN: r184171
Diffstat (limited to 'libstdc++-v3')
-rw-r--r-- | libstdc++-v3/ChangeLog | 13 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/shared_ptr_base.h | 4 | ||||
-rw-r--r-- | libstdc++-v3/include/parallel/compatibility.h | 15 | ||||
-rw-r--r-- | libstdc++-v3/include/profile/impl/profiler_state.h | 2 | ||||
-rw-r--r-- | libstdc++-v3/include/tr1/shared_ptr.h | 4 | ||||
-rw-r--r-- | libstdc++-v3/libsupc++/guard.cc | 7 |
6 files changed, 29 insertions, 16 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index af3f50a..723007c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,16 @@ +2012-02-13 Richard Henderson <rth@redhat.com> + + PR libstdc++/51798 continued. + * include/bits/shared_ptr_base.h + (_Sp_counted_base<_S_atomic>::_M_add_ref_lock): Hoist initial load + outside compare_exchange loop. + * include/tr1/shared_ptr.h: Same. + * include/parallel/compatibility.h (__compare_and_swap_32): Use strong + version of compare_exchange. + (__compare_and_swap_64): Same. + * include/profile/impl/profiler_state.h (__gnu_profile::__turn): Same. + * libsupc++/guard.cc (__cxa_guard_acquire): Same. + 2012-02-10 Benjamin Kosnik <bkoz@redhat.com> Jonathan Wakely <jwakely.gcc@gmail.com> diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index ebdc7ed..c48c18e 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -236,13 +236,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_add_ref_lock() { // Perform lock-free add-if-not-zero operation. - _Atomic_word __count; + _Atomic_word __count = _M_use_count; do { - __count = _M_use_count; if (__count == 0) __throw_bad_weak_ptr(); - // Replace the current counter value with the old value + 1, as // long as it's not changed meanwhile. } diff --git a/libstdc++-v3/include/parallel/compatibility.h b/libstdc++-v3/include/parallel/compatibility.h index 460345e..ed75215 100644 --- a/libstdc++-v3/include/parallel/compatibility.h +++ b/libstdc++-v3/include/parallel/compatibility.h @@ -252,8 +252,9 @@ namespace __gnu_parallel __replacement, __comparand) == __comparand; #elif defined(__GNUC__) - return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, true, - __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); + return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, + false, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); #elif defined(__SUNPRO_CC) && defined(__sparc) return atomic_cas_32((volatile unsigned int*)__ptr, __comparand, __replacement) == __comparand; @@ -299,13 +300,15 @@ namespace __gnu_parallel #endif #elif defined(__GNUC__) && defined(__x86_64) - return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, true, - __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); + return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, + false, __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED); #elif defined(__GNUC__) && defined(__i386) && \ (defined(__i686) || defined(__pentium4) || defined(__athlon) \ || defined(__k8) || defined(__core2)) - return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, true, - __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); + return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, + false, __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 573aa0e..d48801a 100644 --- a/libstdc++-v3/include/profile/impl/profiler_state.h +++ b/libstdc++-v3/include/profile/impl/profiler_state.h @@ -48,7 +48,7 @@ namespace __gnu_profile { __state_type inv(__INVALID); return __atomic_compare_exchange_n(&_GLIBCXX_PROFILE_DATA(__state), - &inv, __s, true, __ATOMIC_ACQ_REL, + &inv, __s, false, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED); } diff --git a/libstdc++-v3/include/tr1/shared_ptr.h b/libstdc++-v3/include/tr1/shared_ptr.h index 723e317..5a1eb03 100644 --- a/libstdc++-v3/include/tr1/shared_ptr.h +++ b/libstdc++-v3/include/tr1/shared_ptr.h @@ -237,13 +237,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_add_ref_lock() { // Perform lock-free add-if-not-zero operation. - _Atomic_word __count; + _Atomic_word __count = _M_use_count; do { - __count = _M_use_count; if (__count == 0) __throw_bad_weak_ptr(); - // Replace the current counter value with the old value + 1, as // long as it's not changed meanwhile. } diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc index b7b8d3f..adc9608 100644 --- a/libstdc++-v3/libsupc++/guard.cc +++ b/libstdc++-v3/libsupc++/guard.cc @@ -251,8 +251,9 @@ namespace __cxxabiv1 while (1) { - if (__atomic_compare_exchange_n(gi, &expected, pending_bit, true, - __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) + if (__atomic_compare_exchange_n(gi, &expected, pending_bit, false, + __ATOMIC_ACQ_REL, + __ATOMIC_RELAXED)) { // This thread should do the initialization. return 1; @@ -266,7 +267,7 @@ namespace __cxxabiv1 if (expected == pending_bit) { int newv = expected | waiting_bit; - if (!__atomic_compare_exchange_n(gi, &expected, newv, true, + if (!__atomic_compare_exchange_n(gi, &expected, newv, false, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) continue; |