< 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 >