Use atomics in guard.cc.
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
This commit is contained in:
parent
40ad260d6c
commit
57e6d9be77
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue