< prev index next >

src/hotspot/share/utilities/waitBarrier_generic.cpp

Print this page
rev 53078 : 8214271: Fast primitive to wake many threads
Reviewed-by:
rev 53079 : [mq]: fix-sema

@@ -35,16 +35,10 @@
   _barrier_tag = barrier_tag;
   _waiters = 0;
   OrderAccess::fence();
 }
 
-void GenericWaitBarrier::disarm() {
-  assert(_barrier_tag != 0, "Not armed");
-  _barrier_tag = 0;
-  OrderAccess::fence();
-}
-
 int GenericWaitBarrier::wake_if_needed() {
   assert(_barrier_tag == 0, "Not disarmed");
   int w = _waiters;
   if (w == 0) {
     // Load of _barrier_threads in caller must not pass the load of _waiters.

@@ -60,11 +54,14 @@
   }
   return w;
 }
 
 void GenericWaitBarrier::wake() {
-  assert(_barrier_tag == 0, "Not disarmed");
+  assert(_barrier_tag != 0, "Not armed");
+  _barrier_tag = 0;
+  // Loads of _barrier_threads/_waiters must not float above disarm store.
+  OrderAccess::fence();
   int left;
   SpinYield sp;
   do {
     left = GenericWaitBarrier::wake_if_needed();
     if (left == 0 && _barrier_threads > 0) {

@@ -76,10 +73,14 @@
   OrderAccess::fence();
 }
 
 void GenericWaitBarrier::wait(int barrier_tag) {
   assert(barrier_tag != 0, "Trying to wait on disarmed value");
+  if (barrier_tag == 0 && barrier_tag != _barrier_tag) {
+    OrderAccess::fence();
+    return;
+  }
   Atomic::add(1, &_barrier_threads);
   if (barrier_tag != 0 && barrier_tag == _barrier_tag) {
     Atomic::add(1, &_waiters);
     _sem_barrier.wait();
     // We help out with posting, but we need to do so before we decrement the
< prev index next >