src/share/vm/utilities/taskqueue.hpp
Print this page
rev 4231 : Fix memory ordering in taskqueue for platforms with weak memory ordering (PPC).
Add fence as described in "Correct and Efficient Work-Stealing for Weak Memory Models;
Le, Pop, Cohen, Nardelli; PPoPP 13". With four or more GC threads bottom can be
older than age in get_bottom().
*** 388,398 ****
}
template<class E, MEMFLAGS F, unsigned int N>
bool GenericTaskQueue<E, F, N>::pop_global(E& t) {
Age oldAge = _age.get();
! uint localBot = _bottom;
uint n_elems = size(localBot, oldAge.top());
if (n_elems == 0) {
return false;
}
--- 388,405 ----
}
template<class E, MEMFLAGS F, unsigned int N>
bool GenericTaskQueue<E, F, N>::pop_global(E& t) {
Age oldAge = _age.get();
! // Architectures with weak memory model require a fence here. The
! // fence has a cumulative effect on getting age and getting bottom.
! // This way it is guaranteed that bottom is not older than age,
! // what is crucial for the correctness of the algorithm.
! #if (defined ARM || defined IA64 || defined PPC64)
! OrderAccess::fence();
! #endif
! uint localBot = OrderAccess::load_acquire((volatile juint*)&_bottom);
uint n_elems = size(localBot, oldAge.top());
if (n_elems == 0) {
return false;
}
*** 632,642 ****
};
template<class E, MEMFLAGS F, unsigned int N> inline bool
GenericTaskQueue<E, F, N>::push(E t) {
uint localBot = _bottom;
! assert((localBot >= 0) && (localBot < N), "_bottom out of range.");
idx_t top = _age.top();
uint dirty_n_elems = dirty_size(localBot, top);
assert(dirty_n_elems < N, "n_elems out of range.");
if (dirty_n_elems < max_elems()) {
// g++ complains if the volatile result of the assignment is unused.
--- 639,649 ----
};
template<class E, MEMFLAGS F, unsigned int N> inline bool
GenericTaskQueue<E, F, N>::push(E t) {
uint localBot = _bottom;
! assert(localBot < N, "_bottom out of range.");
idx_t top = _age.top();
uint dirty_n_elems = dirty_size(localBot, top);
assert(dirty_n_elems < N, "n_elems out of range.");
if (dirty_n_elems < max_elems()) {
// g++ complains if the volatile result of the assignment is unused.