diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 91a5d885228..444d24e068e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,21 @@ +2015-06-12 Ramana Radhakrishnan + + 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 * include/std/tuple (__is_tuple_like_impl): Disambiguate array in diff --git a/libstdc++-v3/config/cpu/generic/atomic_word.h b/libstdc++-v3/config/cpu/generic/atomic_word.h index 19038bb6e06..ccf1e5a5ab1 100644 --- a/libstdc++-v3/config/cpu/generic/atomic_word.h +++ b/libstdc++-v3/config/cpu/generic/atomic_word.h @@ -31,17 +31,10 @@ 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 diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h b/libstdc++-v3/include/bits/shared_ptr_base.h index 081df8781a3..aec10fecdbf 100644 --- a/libstdc++-v3/include/bits/shared_ptr_base.h +++ b/libstdc++-v3/include/bits/shared_ptr_base.h @@ -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(); } diff --git a/libstdc++-v3/include/ext/atomicity.h b/libstdc++-v3/include/ext/atomicity.h index aff33f84354..6d32cc48b4a 100644 --- a/libstdc++-v3/include/ext/atomicity.h +++ b/libstdc++-v3/include/ext/atomicity.h @@ -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 diff --git a/libstdc++-v3/include/tr1/shared_ptr.h b/libstdc++-v3/include/tr1/shared_ptr.h index ebb9d3621d7..a1c7d720307 100644 --- a/libstdc++-v3/include/tr1/shared_ptr.h +++ b/libstdc++-v3/include/tr1/shared_ptr.h @@ -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(); } diff --git a/libstdc++-v3/libsupc++/guard.cc b/libstdc++-v3/libsupc++/guard.cc index 9f19fd462ef..4a2cfe938a9 100644 --- a/libstdc++-v3/libsupc++/guard.cc +++ b/libstdc++-v3/libsupc++/guard.cc @@ -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(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(g); + unsigned char val = 1; + __atomic_store (__p, &val, __ATOMIC_RELEASE); } # define _GLIBCXX_GUARD_SET_AND_RELEASE(G) __set_and_release (G) # endif 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 62555225432..fdfb7d93a72 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,7 +32,7 @@ void test01() { X* px = 0; std::shared_ptr p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 891 } + // { dg-error "incomplete" "" { target *-*-* } 889 } std::shared_ptr p9(ap()); // { dg-error "here" } // { dg-error "incomplete" "" { target *-*-* } 307 } diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc index 3f6c4ae97fc..10074c149fa 100644 --- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc +++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/void_neg.cc @@ -25,5 +25,5 @@ void test01() { std::shared_ptr p((void*)nullptr); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 890 } + // { dg-error "incomplete" "" { target *-*-* } 888 } } 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 276c6a53337..3f44eb7292d 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 @@ -32,8 +32,8 @@ void test01() { X* px = 0; std::tr1::shared_ptr p1(px); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 556 } + // { dg-error "incomplete" "" { target *-*-* } 554 } std::tr1::shared_ptr p9(ap()); // { dg-error "here" } - // { dg-error "incomplete" "" { target *-*-* } 595 } + // { dg-error "incomplete" "" { target *-*-* } 593 } }