8012144: multiple SIGSEGVs fails on staxf

Forward port of 7u change to add additional fence() on RMO platforms, with a load_acquire on all platforms

Reviewed-by: dholmes, kvn
This commit is contained in:
Vladimir Danushevsky 2013-08-06 20:01:40 -04:00
parent 0c24c1a1fc
commit ddf5fcb7c2

View file

@ -395,7 +395,13 @@ bool GenericTaskQueue<E, F, N>::pop_local_slow(uint localBot, Age oldAge) {
template<class E, MEMFLAGS F, unsigned int N> template<class E, MEMFLAGS F, unsigned int N>
bool GenericTaskQueue<E, F, N>::pop_global(E& t) { bool GenericTaskQueue<E, F, N>::pop_global(E& t) {
Age oldAge = _age.get(); Age oldAge = _age.get();
uint localBot = _bottom; // Architectures with weak memory model require a barrier here
// to guarantee that bottom is not older than age,
// which is crucial for the correctness of the algorithm.
#if !(defined SPARC || defined IA32 || defined AMD64)
OrderAccess::fence();
#endif
uint localBot = OrderAccess::load_acquire((volatile juint*)&_bottom);
uint n_elems = size(localBot, oldAge.top()); uint n_elems = size(localBot, oldAge.top());
if (n_elems == 0) { if (n_elems == 0) {
return false; return false;
@ -644,7 +650,7 @@ public:
template<class E, MEMFLAGS F, unsigned int N> inline bool template<class E, MEMFLAGS F, unsigned int N> inline bool
GenericTaskQueue<E, F, N>::push(E t) { GenericTaskQueue<E, F, N>::push(E t) {
uint localBot = _bottom; uint localBot = _bottom;
assert((localBot >= 0) && (localBot < N), "_bottom out of range."); assert(localBot < N, "_bottom out of range.");
idx_t top = _age.top(); idx_t top = _age.top();
uint dirty_n_elems = dirty_size(localBot, top); uint dirty_n_elems = dirty_size(localBot, top);
assert(dirty_n_elems < N, "n_elems out of range."); assert(dirty_n_elems < N, "n_elems out of range.");