PR libstdc++/51798 continued
authorRichard Henderson <rth@redhat.com>
Mon, 13 Feb 2012 21:30:31 +0000 (13:30 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 13 Feb 2012 21:30:31 +0000 (13:30 -0800)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/shared_ptr_base.h
libstdc++-v3/include/parallel/compatibility.h
libstdc++-v3/include/profile/impl/profiler_state.h
libstdc++-v3/include/tr1/shared_ptr.h
libstdc++-v3/libsupc++/guard.cc

index af3f50a..723007c 100644 (file)
@@ -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>
 
index ebdc7ed..c48c18e 100644 (file)
@@ -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. 
        }
index 460345e..ed75215 100644 (file)
@@ -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;
index 573aa0e..d48801a 100644 (file)
@@ -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);
   }
 
index 723e317..5a1eb03 100644 (file)
@@ -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. 
        }
index b7b8d3f..adc9608 100644 (file)
@@ -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;