< prev index next >

src/hotspot/share/gc/shared/taskqueue.inline.hpp

Print this page
rev 55962 : 8229422: Taskqueue: Outdated selection of weak memory model platforms
Reviewed-by:


 190     // The algorithm may fail if _age.get() reads an older value than _age.top().
 191     OrderAccess::loadload();
 192     return pop_local_slow(localBot, _age.get());
 193   }
 194 }
 195 
 196 template <class E, MEMFLAGS F, unsigned int N>
 197 bool OverflowTaskQueue<E, F, N>::pop_overflow(E& t)
 198 {
 199   if (overflow_empty()) return false;
 200   t = overflow_stack()->pop();
 201   return true;
 202 }
 203 
 204 template<class E, MEMFLAGS F, unsigned int N>
 205 bool GenericTaskQueue<E, F, N>::pop_global(volatile E& t) {
 206   Age oldAge = _age.get();
 207   // Architectures with weak memory model require a barrier here
 208   // to guarantee that bottom is not older than age,
 209   // which is crucial for the correctness of the algorithm.
 210 #if !(defined SPARC || defined IA32 || defined AMD64)
 211   OrderAccess::fence();
 212 #endif
 213   uint localBot = OrderAccess::load_acquire(&_bottom);
 214   uint n_elems = size(localBot, oldAge.top());
 215   if (n_elems == 0) {
 216     return false;
 217   }
 218 
 219   // g++ complains if the volatile result of the assignment is
 220   // unused, so we cast the volatile away.  We cannot cast directly
 221   // to void, because gcc treats that as not using the result of the
 222   // assignment.  However, casting to E& means that we trigger an
 223   // unused-value warning.  So, we cast the E& to void.
 224   (void) const_cast<E&>(t = _elems[oldAge.top()]);
 225   Age newAge(oldAge);
 226   newAge.increment();
 227   Age resAge = _age.cmpxchg(newAge, oldAge);
 228 
 229   // Note that using "_bottom" here might fail, since a pop_local might
 230   // have decremented it.




 190     // The algorithm may fail if _age.get() reads an older value than _age.top().
 191     OrderAccess::loadload();
 192     return pop_local_slow(localBot, _age.get());
 193   }
 194 }
 195 
 196 template <class E, MEMFLAGS F, unsigned int N>
 197 bool OverflowTaskQueue<E, F, N>::pop_overflow(E& t)
 198 {
 199   if (overflow_empty()) return false;
 200   t = overflow_stack()->pop();
 201   return true;
 202 }
 203 
 204 template<class E, MEMFLAGS F, unsigned int N>
 205 bool GenericTaskQueue<E, F, N>::pop_global(volatile E& t) {
 206   Age oldAge = _age.get();
 207   // Architectures with weak memory model require a barrier here
 208   // to guarantee that bottom is not older than age,
 209   // which is crucial for the correctness of the algorithm.
 210 #ifndef CPU_MULTI_COPY_ATOMIC
 211   OrderAccess::fence();
 212 #endif
 213   uint localBot = OrderAccess::load_acquire(&_bottom);
 214   uint n_elems = size(localBot, oldAge.top());
 215   if (n_elems == 0) {
 216     return false;
 217   }
 218 
 219   // g++ complains if the volatile result of the assignment is
 220   // unused, so we cast the volatile away.  We cannot cast directly
 221   // to void, because gcc treats that as not using the result of the
 222   // assignment.  However, casting to E& means that we trigger an
 223   // unused-value warning.  So, we cast the E& to void.
 224   (void) const_cast<E&>(t = _elems[oldAge.top()]);
 225   Age newAge(oldAge);
 226   newAge.increment();
 227   Age resAge = _age.cmpxchg(newAge, oldAge);
 228 
 229   // Note that using "_bottom" here might fail, since a pop_local might
 230   // have decremented it.


< prev index next >