Commit b2cb6964 by Richard Henderson Committed by Richard Henderson

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
parent 67b977ad
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> 2012-02-10 Benjamin Kosnik <bkoz@redhat.com>
Jonathan Wakely <jwakely.gcc@gmail.com> Jonathan Wakely <jwakely.gcc@gmail.com>
......
...@@ -236,13 +236,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -236,13 +236,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_add_ref_lock() _M_add_ref_lock()
{ {
// Perform lock-free add-if-not-zero operation. // Perform lock-free add-if-not-zero operation.
_Atomic_word __count; _Atomic_word __count = _M_use_count;
do do
{ {
__count = _M_use_count;
if (__count == 0) if (__count == 0)
__throw_bad_weak_ptr(); __throw_bad_weak_ptr();
// Replace the current counter value with the old value + 1, as // Replace the current counter value with the old value + 1, as
// long as it's not changed meanwhile. // long as it's not changed meanwhile.
} }
......
...@@ -252,8 +252,9 @@ namespace __gnu_parallel ...@@ -252,8 +252,9 @@ namespace __gnu_parallel
__replacement, __comparand) __replacement, __comparand)
== __comparand; == __comparand;
#elif defined(__GNUC__) #elif defined(__GNUC__)
return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, true, return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement,
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED); false, __ATOMIC_ACQ_REL,
__ATOMIC_RELAXED);
#elif defined(__SUNPRO_CC) && defined(__sparc) #elif defined(__SUNPRO_CC) && defined(__sparc)
return atomic_cas_32((volatile unsigned int*)__ptr, __comparand, return atomic_cas_32((volatile unsigned int*)__ptr, __comparand,
__replacement) == __comparand; __replacement) == __comparand;
...@@ -299,13 +300,15 @@ namespace __gnu_parallel ...@@ -299,13 +300,15 @@ namespace __gnu_parallel
#endif #endif
#elif defined(__GNUC__) && defined(__x86_64) #elif defined(__GNUC__) && defined(__x86_64)
return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, true, return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement,
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED); false, __ATOMIC_ACQ_REL,
__ATOMIC_RELAXED);
#elif defined(__GNUC__) && defined(__i386) && \ #elif defined(__GNUC__) && defined(__i386) && \
(defined(__i686) || defined(__pentium4) || defined(__athlon) \ (defined(__i686) || defined(__pentium4) || defined(__athlon) \
|| defined(__k8) || defined(__core2)) || defined(__k8) || defined(__core2))
return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement, true, return __atomic_compare_exchange_n(__ptr, &__comparand, __replacement,
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED); false, __ATOMIC_ACQ_REL,
__ATOMIC_RELAXED);
#elif defined(__SUNPRO_CC) && defined(__sparc) #elif defined(__SUNPRO_CC) && defined(__sparc)
return atomic_cas_64((volatile unsigned long long*)__ptr, return atomic_cas_64((volatile unsigned long long*)__ptr,
__comparand, __replacement) == __comparand; __comparand, __replacement) == __comparand;
......
...@@ -48,7 +48,7 @@ namespace __gnu_profile ...@@ -48,7 +48,7 @@ namespace __gnu_profile
{ {
__state_type inv(__INVALID); __state_type inv(__INVALID);
return __atomic_compare_exchange_n(&_GLIBCXX_PROFILE_DATA(__state), return __atomic_compare_exchange_n(&_GLIBCXX_PROFILE_DATA(__state),
&inv, __s, true, __ATOMIC_ACQ_REL, &inv, __s, false, __ATOMIC_ACQ_REL,
__ATOMIC_RELAXED); __ATOMIC_RELAXED);
} }
......
...@@ -237,13 +237,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -237,13 +237,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_add_ref_lock() _M_add_ref_lock()
{ {
// Perform lock-free add-if-not-zero operation. // Perform lock-free add-if-not-zero operation.
_Atomic_word __count; _Atomic_word __count = _M_use_count;
do do
{ {
__count = _M_use_count;
if (__count == 0) if (__count == 0)
__throw_bad_weak_ptr(); __throw_bad_weak_ptr();
// Replace the current counter value with the old value + 1, as // Replace the current counter value with the old value + 1, as
// long as it's not changed meanwhile. // long as it's not changed meanwhile.
} }
......
...@@ -251,8 +251,9 @@ namespace __cxxabiv1 ...@@ -251,8 +251,9 @@ namespace __cxxabiv1
while (1) while (1)
{ {
if (__atomic_compare_exchange_n(gi, &expected, pending_bit, true, if (__atomic_compare_exchange_n(gi, &expected, pending_bit, false,
__ATOMIC_ACQ_REL, __ATOMIC_RELAXED)) __ATOMIC_ACQ_REL,
__ATOMIC_RELAXED))
{ {
// This thread should do the initialization. // This thread should do the initialization.
return 1; return 1;
...@@ -266,7 +267,7 @@ namespace __cxxabiv1 ...@@ -266,7 +267,7 @@ namespace __cxxabiv1
if (expected == pending_bit) if (expected == pending_bit)
{ {
int newv = expected | waiting_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_ACQ_REL,
__ATOMIC_RELAXED)) __ATOMIC_RELAXED))
continue; continue;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment