+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
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
// 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.
{
// 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();
}
// 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
// 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.
{
// 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();
}
# 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
{
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 }
void test01()
{
std::shared_ptr<void> p((void*)nullptr); // { dg-error "here" }
- // { dg-error "incomplete" "" { target *-*-* } 890 }
+ // { dg-error "incomplete" "" { target *-*-* } 888 }
}
{
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 }
}