Use atomics in guard.cc.
authorRamana Radhakrishnan <ramana.radhakrishnan@arm.com>
Fri, 12 Jun 2015 09:49:41 +0000 (09:49 +0000)
committerRamana Radhakrishnan <ramana@gcc.gnu.org>
Fri, 12 Jun 2015 09:49:41 +0000 (09:49 +0000)
This provides proper definitions for _GLIBCXX_READ_MEM_BARRIER and
_GLIBCXX_WRITE_MEM_BARRIER, rewrites the guards in terms of proper
atomic extensions and removes internal uses of
_GLIBCXX_READ_MEM_BARRIER and _GLIBCXX_WRITE_MEM_BARRIER and replaces
them with equivalent atomics.

2015-06-12  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>

PR target/66200
PR c++/66192
* * config/cpu/generic/atomic_word.h (_GLIBCXX_READ_MEM_BARRIER): Define
        (_GLIBCXX_WRITE_MEM_BARRIER): Likewise
        * include/bits/shared_ptr_base.h: Use ACQ_REL barrier.
        * include/ext/atomicity.h: Likewise.
        * include/tr1/shared_ptr.h: Likewise.
        * libsupc++/guard.cc (__test_and_acquire): Rewrite with atomics.
        Update comment.
        (__set_and_release): Likewise.
        * testsuite/20_util/shared_ptr/cons/43820_neg.cc (test01): Adjust for
line numbers.
        * testsuite/20_util/shared_ptr/cons/void_neg.cc: Likewise.
        * testsuite/tr1/2_general_utilities/shared_ptr/cons/43820_neg.cc:
Likewise.

From-SVN: r224411

libstdc++-v3/ChangeLog
libstdc++-v3/config/cpu/generic/atomic_word.h
libstdc++-v3/include/bits/shared_ptr_base.h
libstdc++-v3/include/ext/atomicity.h
libstdc++-v3/include/tr1/shared_ptr.h
libstdc++-v3/libsupc++/guard.cc
libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc
libstdc++-v3/testsuite/tr1/2_general_utilities/shared_ptr/cons/43820_neg.cc

index 91a5d8852281e6ce51003f323e4b0b11961299f2..444d24e068e18b95cffa7e06ca3309a5a5cda43e 100644 (file)
@@ -1,3 +1,21 @@
+2015-06-12  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
+
+       PR target/66200
+       PR c++/66192
+       * * config/cpu/generic/atomic_word.h (_GLIBCXX_READ_MEM_BARRIER): Define
+        (_GLIBCXX_WRITE_MEM_BARRIER): Likewise
+        * include/bits/shared_ptr_base.h: Use ACQ_REL barrier.
+        * include/ext/atomicity.h: Likewise.
+        * include/tr1/shared_ptr.h: Likewise.
+        * libsupc++/guard.cc (__test_and_acquire): Rewrite with atomics.
+        Update comment.
+        (__set_and_release): Likewise.
+        * testsuite/20_util/shared_ptr/cons/43820_neg.cc (test01): Adjust for
+       line numbers.
+        * testsuite/20_util/shared_ptr/cons/void_neg.cc: Likewise.
+        * testsuite/tr1/2_general_utilities/shared_ptr/cons/43820_neg.cc:
+       Likewise.
+
 2015-06-12  Jonathan Wakely  <jwakely@redhat.com>
 
        * include/std/tuple (__is_tuple_like_impl): Disambiguate array in
index 19038bb6e06131cb7cd3d166fb0195d081389712..ccf1e5a5ab167653fadf411b61155dc61ee03dff 100644 (file)
 
 typedef int _Atomic_word;
 
-// Define these two macros using the appropriate memory barrier for the target.
-// The commented out versions below are the defaults.
-// See ia64/atomic_word.h for an alternative approach.
-
-// This one prevents loads from being hoisted across the barrier;
-// in other words, this is a Load-Load acquire barrier.
-// This is necessary iff TARGET_RELAXED_ORDERING is defined in tm.h.  
-// #define _GLIBCXX_READ_MEM_BARRIER __asm __volatile ("":::"memory")
-
-// This one prevents stores from being sunk across the barrier; in other
-// words, a Store-Store release barrier.
-// #define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile ("":::"memory")
+
+// This is a memory order acquire fence.
+#define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE)
+// This is a memory order release fence.
+#define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE)
 
 #endif 
index 081df8781a3702895509bd950685907c32f669e9..aec10fecdbf52a013bca57546d6ee9fca13cc989 100644 (file)
@@ -154,8 +154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
            if (_Mutex_base<_Lp>::_S_need_barriers)
              {
-               _GLIBCXX_READ_MEM_BARRIER;
-               _GLIBCXX_WRITE_MEM_BARRIER;
+               __atomic_thread_fence (__ATOMIC_ACQ_REL);
              }
 
             // Be race-detector-friendly.  For more info see bits/c++config.
@@ -185,8 +184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              {
                // See _M_release(),
                // destroy() must observe results of dispose()
-               _GLIBCXX_READ_MEM_BARRIER;
-               _GLIBCXX_WRITE_MEM_BARRIER;
+               __atomic_thread_fence (__ATOMIC_ACQ_REL);
              }
            _M_destroy();
          }
index aff33f84354a17afd0d057bdee4e586cee10ebb8..6d32cc48b4ad16f8d137d4c35efcdf14c1137629 100644 (file)
@@ -108,10 +108,10 @@ _GLIBCXX_END_NAMESPACE_VERSION
 // that the compiler doesn't reorder memory accesses across the
 // barriers.
 #ifndef _GLIBCXX_READ_MEM_BARRIER
-#define _GLIBCXX_READ_MEM_BARRIER __asm __volatile ("":::"memory")
+#define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE)
 #endif
 #ifndef _GLIBCXX_WRITE_MEM_BARRIER
-#define _GLIBCXX_WRITE_MEM_BARRIER __asm __volatile ("":::"memory")
+#define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE)
 #endif
 
 #endif 
index ebb9d3621d7f10846607bbd0224415f0308e6b24..a1c7d720307aefe279eec425baf36727070e72e5 100644 (file)
@@ -145,8 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            // See http://gcc.gnu.org/ml/libstdc++/2005-11/msg00136.html
            if (_Mutex_base<_Lp>::_S_need_barriers)
              {
-               _GLIBCXX_READ_MEM_BARRIER;
-               _GLIBCXX_WRITE_MEM_BARRIER;
+               __atomic_thread_fence (__ATOMIC_ACQ_REL);
              }
 
             // Be race-detector-friendly.  For more info see bits/c++config.
@@ -176,8 +175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
              {
                // See _M_release(),
                // destroy() must observe results of dispose()
-               _GLIBCXX_READ_MEM_BARRIER;
-               _GLIBCXX_WRITE_MEM_BARRIER;
+               __atomic_thread_fence (__ATOMIC_ACQ_REL);
              }
            _M_destroy();
          }
index 9f19fd462ef6c7c626349255dd9927afa8db6276..4a2cfe938a9d0dc3e1c1c4cc44b42a576ede041e 100644 (file)
@@ -107,22 +107,31 @@ namespace
 # endif
 
 # ifndef _GLIBCXX_GUARD_TEST_AND_ACQUIRE
+
+// Test the guard variable with a memory load with
+// acquire semantics.
+
 inline bool
 __test_and_acquire (__cxxabiv1::__guard *g)
 {
-  bool b = _GLIBCXX_GUARD_TEST (g);
-  _GLIBCXX_READ_MEM_BARRIER;
-  return b;
+  unsigned char __c;
+  unsigned char *__p = reinterpret_cast<unsigned char *>(g);
+  __atomic_load (__p, &__c,  __ATOMIC_ACQUIRE);
+  return _GLIBCXX_GUARD_TEST(&__c);
 }
 #  define _GLIBCXX_GUARD_TEST_AND_ACQUIRE(G) __test_and_acquire (G)
 # endif
 
 # ifndef _GLIBCXX_GUARD_SET_AND_RELEASE
+
+// Set the guard variable to 1 with memory order release semantics.
+
 inline void
 __set_and_release (__cxxabiv1::__guard *g)
 {
-  _GLIBCXX_WRITE_MEM_BARRIER;
-  _GLIBCXX_GUARD_SET (g);
+  unsigned char *__p = reinterpret_cast<unsigned char *>(g);
+  unsigned char val = 1;
+  __atomic_store (__p, &val, __ATOMIC_RELEASE);
 }
 #  define _GLIBCXX_GUARD_SET_AND_RELEASE(G) __set_and_release (G)
 # endif
index 62555225432e4ac6202511dd413e94057c3982c7..fdfb7d93a72966d12a0aff11d6e8b5efca15cfaa 100644 (file)
@@ -32,7 +32,7 @@ void test01()
 {
   X* px = 0;
   std::shared_ptr<X> p1(px);   // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 891 }
+  // { dg-error "incomplete" "" { target *-*-* } 889 }
 
   std::shared_ptr<X> p9(ap());  // { dg-error "here" }
   // { dg-error "incomplete" "" { target *-*-* } 307 }
index 3f6c4ae97fc18cdbb068afa2f48b023fe9fa1620..10074c149fa8a268e233ef0252d8479557b677c4 100644 (file)
@@ -25,5 +25,5 @@
 void test01()
 {
   std::shared_ptr<void> p((void*)nullptr);   // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 890 }
+  // { dg-error "incomplete" "" { target *-*-* } 888 }
 }
index 276c6a533379d4b8e22877fe76b3eafd94bb5794..3f44eb7292d3363377a80c485c42c0d1f96fcd0e 100644 (file)
@@ -32,8 +32,8 @@ void test01()
 {
   X* px = 0;
   std::tr1::shared_ptr<X> p1(px);   // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 556 }
+  // { dg-error "incomplete" "" { target *-*-* } 554 }
 
   std::tr1::shared_ptr<X> p9(ap());  // { dg-error "here" }
-  // { dg-error "incomplete" "" { target *-*-* } 595 }
+  // { dg-error "incomplete" "" { target *-*-* } 593 }
 }