public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [v3] libstdc++/51798
@ 2012-02-09 23:47 Benjamin Kosnik
  2012-02-11  1:11 ` Richard Henderson
  0 siblings, 1 reply; 5+ messages in thread
From: Benjamin Kosnik @ 2012-02-09 23:47 UTC (permalink / raw)
  To: gcc-patches, libstdc++, jakub

[-- Attachment #1: Type: text/plain, Size: 256 bytes --]


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

[-- Attachment #2: 20120209-2.patch --]
[-- Type: text/x-patch, Size: 30016 bytes --]


2012-02-09  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.


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<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 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<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 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<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 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 @@
 // <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 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<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 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<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 }
 
 }

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [v3] libstdc++/51798
  2012-02-09 23:47 [v3] libstdc++/51798 Benjamin Kosnik
@ 2012-02-11  1:11 ` Richard Henderson
  2012-02-11 13:29   ` Jonathan Wakely
  2012-02-14  6:44   ` Benjamin Kosnik
  0 siblings, 2 replies; 5+ messages in thread
From: Richard Henderson @ 2012-02-11  1:11 UTC (permalink / raw)
  To: Benjamin Kosnik; +Cc: gcc-patches, libstdc++, jakub

[-- Attachment #1: Type: text/plain, Size: 1683 bytes --]

On 02/09/2012 03:24 PM, Benjamin Kosnik wrote:
> 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
> 
> 
> 20120209-2.patch
> 
> 
> 2012-02-09  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.

The patch uses the weak version of compare_exchange universally, which
is incorrect in a number of cases.  You wouldn't see this on x86_64;
you'd have to use a ll/sc target such as powerpc.

In addition to changing several uses to strong compare_exchange, I also
optimize the idiom

	do
	  {
            var = *m;
	    newval = ...;
	  }
	while (!atomic_compare_exchange(m, &var, newval, ...));

With the new builtins, VAR is updated with the current value of the 
memory (regardless of the weak setting), so the initial read from *M
can be hoisted outside the loop.

Ok?


r~

[-- Attachment #2: z --]
[-- Type: text/plain, Size: 5117 bytes --]

	* 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.



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..8a65c9e 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_ACQ_REL);
 #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_ACQ_REL);
 #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_ACQ_REL);
 #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..37d761f 100644
--- a/libstdc++-v3/include/profile/impl/profiler_state.h
+++ b/libstdc++-v3/include/profile/impl/profiler_state.h
@@ -48,8 +48,8 @@ namespace __gnu_profile
   { 
     __state_type inv(__INVALID);
     return __atomic_compare_exchange_n(&_GLIBCXX_PROFILE_DATA(__state),
-				       &inv, __s, true, __ATOMIC_ACQ_REL, 
-				       __ATOMIC_RELAXED);
+				       &inv, __s, false, __ATOMIC_ACQ_REL, 
+				       __ATOMIC_ACQ_REL);
   }
 
   inline bool
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..3f39dce 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_ACQ_REL))
 	      {
 		// This thread should do the initialization.
 		return 1;
@@ -266,9 +267,9 @@ 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))
+						  __ATOMIC_ACQ_REL))
 		   continue;
 		 
 		 expected = newv;

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [v3] libstdc++/51798
  2012-02-11  1:11 ` Richard Henderson
@ 2012-02-11 13:29   ` Jonathan Wakely
  2012-02-14  6:44   ` Benjamin Kosnik
  1 sibling, 0 replies; 5+ messages in thread
From: Jonathan Wakely @ 2012-02-11 13:29 UTC (permalink / raw)
  To: Richard Henderson; +Cc: Benjamin Kosnik, gcc-patches, libstdc++, jakub

On 11 February 2012 00:56, Richard Henderson wrote:
>
> Ok?

OK, thanks.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [v3] libstdc++/51798
  2012-02-11  1:11 ` Richard Henderson
  2012-02-11 13:29   ` Jonathan Wakely
@ 2012-02-14  6:44   ` Benjamin Kosnik
  2012-02-17 21:28     ` Benjamin Kosnik
  1 sibling, 1 reply; 5+ messages in thread
From: Benjamin Kosnik @ 2012-02-14  6:44 UTC (permalink / raw)
  To: Richard Henderson; +Cc: gcc-patches, libstdc++, jakub

[-- Attachment #1: Type: text/plain, Size: 723 bytes --]

 
> The patch uses the weak version of compare_exchange universally, which
> is incorrect in a number of cases.  You wouldn't see this on x86_64;
> you'd have to use a ll/sc target such as powerpc.
> 
> In addition to changing several uses to strong compare_exchange, I
> also optimize the idiom
> 
> 	do
> 	  {
>             var = *m;
> 	    newval = ...;
> 	  }
> 	while (!atomic_compare_exchange(m, &var, newval, ...));
> 
> With the new builtins, VAR is updated with the current value of the 
> memory (regardless of the weak setting), so the initial read from *M
> can be hoisted outside the loop.

nice!

> 
> Ok?
 
cool, thanks for reviewing this. 

I fixed up the line numbers for the header file edits.

-benjamin

[-- Attachment #2: 20120213-1.patch --]
[-- Type: text/x-patch, Size: 1927 bytes --]

2012-02-13  Benjamin Kosnik  <bkoz@redhat.com>

	* 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/testsuite/20_util/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
index 0d51663..39f9ce3 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
@@ -32,9 +32,9 @@ void test01()
 {
   X* px = 0;
   std::shared_ptr<X> p1(px);   // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 773 }
+  // { dg-error "incomplete" "" { target *-*-* } 771 }
 
   std::shared_ptr<X> p9(ap());  // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 867 }
+  // { dg-error "incomplete" "" { target *-*-* } 865 }
 
 }
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 ae902dc..0309f8f 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
@@ -1,6 +1,6 @@
 // { dg-do compile }
 
-// Copyright (C) 2010 Free Software Foundation
+// Copyright (C) 2010, 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
@@ -30,9 +30,9 @@ void test01()
 {
   X* px = 0;
   std::tr1::shared_ptr<X> p1(px);   // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 565 }
+  // { dg-error "incomplete" "" { target *-*-* } 563 }
 
   std::tr1::shared_ptr<X> p9(ap());  // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 604 }
+  // { dg-error "incomplete" "" { target *-*-* } 602 }
 
 }

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [v3] libstdc++/51798
  2012-02-14  6:44   ` Benjamin Kosnik
@ 2012-02-17 21:28     ` Benjamin Kosnik
  0 siblings, 0 replies; 5+ messages in thread
From: Benjamin Kosnik @ 2012-02-17 21:28 UTC (permalink / raw)
  To: Benjamin Kosnik; +Cc: Richard Henderson, gcc-patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 204 bytes --]


Noticed that the config for the new atomic builtins was not correct for
targets that did not do link tests. (ie x86-x-cris-elf). Fixed as
follows.

tested x86/linux
tested x86/linux x cris-elf

-benjamin

[-- Attachment #2: 20120217-2.patch --]
[-- Type: text/x-patch, Size: 1577 bytes --]

2012-02-17  Benjamin Kosnik  <bkoz@redhat.com>

        PR libstdc++/51798 continued.
        * acinclude.m4 (GLIBCXX_ENABLE_ATOMIC_BUILTINS): Grep for
        __atomic_, not __sync.


diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 46a5532..b832527 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2824,7 +2824,7 @@ EOF
 
     AC_MSG_CHECKING([for atomic builtins for bool])
     if AC_TRY_EVAL(ac_compile); then
-      if grep __sync_ conftest.s >/dev/null 2>&1 ; then
+      if grep __atomic_ conftest.s >/dev/null 2>&1 ; then
 	glibcxx_cv_atomic_bool=no
       else
 	glibcxx_cv_atomic_bool=yes
@@ -2853,7 +2853,7 @@ EOF
 
     AC_MSG_CHECKING([for atomic builtins for short])
     if AC_TRY_EVAL(ac_compile); then
-      if grep __sync_ conftest.s >/dev/null 2>&1 ; then
+      if grep __atomic_ conftest.s >/dev/null 2>&1 ; then
 	glibcxx_cv_atomic_short=no
       else
 	glibcxx_cv_atomic_short=yes
@@ -2883,7 +2883,7 @@ EOF
 
     AC_MSG_CHECKING([for atomic builtins for int])
     if AC_TRY_EVAL(ac_compile); then
-      if grep __sync_ conftest.s >/dev/null 2>&1 ; then
+      if grep __atomic_ conftest.s >/dev/null 2>&1 ; then
 	glibcxx_cv_atomic_int=no
       else
 	glibcxx_cv_atomic_int=yes
@@ -2912,7 +2912,7 @@ EOF
 
     AC_MSG_CHECKING([for atomic builtins for long long])
     if AC_TRY_EVAL(ac_compile); then
-      if grep __sync_ conftest.s >/dev/null 2>&1 ; then
+      if grep __atomic_ conftest.s >/dev/null 2>&1 ; then
 	glibcxx_cv_atomic_long_long=no
       else
 	glibcxx_cv_atomic_long_long=yes

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-02-17 20:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-09 23:47 [v3] libstdc++/51798 Benjamin Kosnik
2012-02-11  1:11 ` Richard Henderson
2012-02-11 13:29   ` Jonathan Wakely
2012-02-14  6:44   ` Benjamin Kosnik
2012-02-17 21:28     ` Benjamin Kosnik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).