mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-18 22:35:12 +00:00
Strengthen some orderings
This commit is contained in:
parent
556c5201e4
commit
f077eb9eb0
@ -1249,16 +1249,16 @@ public class ForkJoinPool extends AbstractExecutorService
|
||||
*/
|
||||
final void push(ForkJoinTask<?> task, ForkJoinPool pool, int unlock) {
|
||||
ForkJoinTask<?>[] a = array;
|
||||
int b = base, s = top, m;
|
||||
int b = base, s = top, room, m;
|
||||
if (a != null &&
|
||||
(a.length > s + 1 - b || (a = growArray()) != null) &&
|
||||
((room = a.length - (s + 1 - b)) > 0 || (a = growArray()) != null) &&
|
||||
(m = a.length - 1) >= 0) { // else rejected or disabled
|
||||
top = s + 1;
|
||||
U.putReferenceVolatile(a, slotOffset(m & s), task);
|
||||
if (unlock != 1) // release external lock
|
||||
U.putInt(this, PHASE, unlock);
|
||||
if (U.getReferenceAcquire(a, slotOffset(m & (s - 1))) == null &&
|
||||
pool != null)
|
||||
phase = unlock;
|
||||
if ((U.getReferenceAcquire(a, slotOffset(m & (s - 1))) == null ||
|
||||
room <= 0) && pool != null)
|
||||
pool.signalWork(this, s); // may have appeared empty
|
||||
}
|
||||
}
|
||||
@ -1307,13 +1307,16 @@ public class ForkJoinPool extends AbstractExecutorService
|
||||
if (a != null && s - b >= 0 && (cap = a.length) > 0) {
|
||||
if (fifo == 0) {
|
||||
if ((t = (ForkJoinTask<?>)U.getAndSetReference(
|
||||
a, slotOffset((cap - 1) & s), null)) != null)
|
||||
a, slotOffset((cap - 1) & s), null)) != null) {
|
||||
top = s;
|
||||
U.storeFence();
|
||||
}
|
||||
} else {
|
||||
do {
|
||||
if ((t = (ForkJoinTask<?>)U.getAndSetReference(
|
||||
a, slotOffset((cap - 1) & b), null)) != null) {
|
||||
base = b + 1;
|
||||
U.storeFence();
|
||||
break;
|
||||
}
|
||||
if (b == s)
|
||||
@ -1330,10 +1333,7 @@ public class ForkJoinPool extends AbstractExecutorService
|
||||
* Takes next task, if one exists, using configured mode.
|
||||
*/
|
||||
final ForkJoinTask<?> nextLocalTask() {
|
||||
U.loadFence(); // ensure ordering for external callers
|
||||
ForkJoinTask<?> t= nextLocalTask(config & FIFO);
|
||||
U.storeFence();
|
||||
return t;
|
||||
return nextLocalTask(config & FIFO);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1350,10 +1350,11 @@ public class ForkJoinPool extends AbstractExecutorService
|
||||
(internal || (lock = tryLockPhase()) != 1)) {
|
||||
if (top == p && U.compareAndSetReference(a, k, task, null)) {
|
||||
taken = true;
|
||||
U.putIntOpaque(this, TOP, s);
|
||||
top = s;
|
||||
U.storeFence();
|
||||
}
|
||||
if (!internal)
|
||||
U.putIntRelease(this, PHASE, lock + NEXTIDLE);
|
||||
phase = lock + NEXTIDLE;
|
||||
}
|
||||
return taken;
|
||||
}
|
||||
@ -1413,6 +1414,7 @@ public class ForkJoinPool extends AbstractExecutorService
|
||||
/**
|
||||
* Runs the given task, as well as remaining local tasks
|
||||
*/
|
||||
// @jdk.internal.vm.annotation.DontInline
|
||||
final void topLevelExec(ForkJoinTask<?> task, int fifo) {
|
||||
while (task != null) {
|
||||
task.doExec();
|
||||
@ -1452,9 +1454,10 @@ public class ForkJoinPool extends AbstractExecutorService
|
||||
a, slotOffset(s & m), null));
|
||||
top = s;
|
||||
}
|
||||
U.storeFence();
|
||||
}
|
||||
if (!internal)
|
||||
U.putIntRelease(this, PHASE, lock + NEXTIDLE);
|
||||
phase = lock + NEXTIDLE;
|
||||
if (taken)
|
||||
task.doExec();
|
||||
break;
|
||||
@ -1498,10 +1501,12 @@ public class ForkJoinPool extends AbstractExecutorService
|
||||
break;
|
||||
if (taken =
|
||||
(top == p &&
|
||||
U.compareAndSetReference(a, k, t, null)))
|
||||
U.compareAndSetReference(a, k, t, null))) {
|
||||
top = s;
|
||||
U.storeFence();
|
||||
}
|
||||
if (!internal)
|
||||
U.putIntRelease(this, PHASE, lock + NEXTIDLE);
|
||||
phase = lock + NEXTIDLE;
|
||||
if (!taken)
|
||||
break;
|
||||
t.doExec();
|
||||
@ -1537,6 +1542,7 @@ public class ForkJoinPool extends AbstractExecutorService
|
||||
if (base == b && t != null &&
|
||||
U.compareAndSetReference(a, k, t, null)) {
|
||||
base = b + 1;
|
||||
U.storeFence();
|
||||
t.doExec();
|
||||
}
|
||||
}
|
||||
@ -2015,16 +2021,23 @@ public class ForkJoinPool extends AbstractExecutorService
|
||||
}
|
||||
long sp = (phase + NEXTIDLE) & LMASK, pc = ctl;
|
||||
U.putInt(w, WorkQueue.PHASE, phase | IDLE);
|
||||
for (long c;;) { // try to enqueue
|
||||
for (;;) { // try to enqueue
|
||||
long c, e;
|
||||
w.stackPred = (int)pc;
|
||||
if (pc == (pc = U.compareAndExchangeLong(
|
||||
this, CTL, pc, c = ((pc - RC_UNIT) & UMASK) | sp))) {
|
||||
idle = IDLE;
|
||||
if ((c & RC_MASK) == 0L)
|
||||
quiescent(); // check quiescent termination
|
||||
if (((e = runState) & STOP) == 0L &&
|
||||
((e & SHUTDOWN) == 0L || (c & RC_MASK) > 0L ||
|
||||
quiescent() <= 0)) { // spin for approx 1 scan cost
|
||||
int tc = (short)(c >>> TC_SHIFT);
|
||||
int spins = Math.max((tc << 1) + tc, SPIN_WAITS);
|
||||
while ((idle = w.phase & IDLE) != 0 && --spins != 0)
|
||||
Thread.onSpinWait();
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if ((c & RC_MASK) <= (pc & RC_MASK)) {
|
||||
else if ((c & RC_MASK) < (pc & RC_MASK)) {
|
||||
w.phase = phase; // back out if lost to signal
|
||||
break;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user