1608 |
|
if (w != null && (ws = workQueues) != null && (m = ws.length - 1) >= 0) { |
1609 |
|
int ec = w.eventCount; // ec negative if inactive |
1610 |
|
int r = w.seed; r ^= r << 13; r ^= r >>> 17; w.seed = r ^= r << 5; |
1611 |
< |
for (int j = (m << 1) | (ec < 0 ? MIN_RESCANS : 1);;) { |
1611 |
> |
for (int j = (m << 1) | (ec < 0 ? MIN_RESCANS : 0xf);;) { |
1612 |
|
WorkQueue q; int b, s; ForkJoinTask<?>[] a; |
1613 |
|
if ((q = ws[(r - j) & m]) != null && // probably nonempty |
1614 |
|
(b = q.base) - (s = q.top) < 0 && (a = q.array) != null) { |
1623 |
|
signalWork(q); |
1624 |
|
return t; |
1625 |
|
} |
1626 |
< |
if (--j < m) { // restart to revisit |
1627 |
< |
if (ec < 0) // help activate |
1626 |
> |
if (--j < m) { // restart to revisit |
1627 |
> |
if (ec < 0) // help activate |
1628 |
|
signalWork(q); |
1629 |
|
break; |
1630 |
|
} |
1631 |
|
} |
1632 |
|
else if (--j < 0) { |
1633 |
< |
long c = ctl; |
1633 |
> |
long c = ctl; int e; |
1634 |
|
long nc = (long)ec | ((c - AC_UNIT) & (AC_MASK|TC_MASK)); |
1635 |
– |
int e = (int)c; |
1635 |
|
if (plock == ps) { |
1636 |
< |
if (e >= 0 && ec >= 0) { |
1636 |
> |
if ((e = (int)c) < 0) |
1637 |
> |
w.qlock = -1; // pool is terminating |
1638 |
> |
else if (ec >= 0) { |
1639 |
|
w.nextWait = e; // try to enqueue/inactivate |
1640 |
|
w.eventCount = ec | INT_SIGN; |
1641 |
|
if (!U.compareAndSwapLong(this, CTL, c, nc)) |
1664 |
|
* @param c the ctl value triggering possible quiescence |
1665 |
|
*/ |
1666 |
|
private final void onEmptyScan(WorkQueue w, long c) { |
1667 |
< |
int ec, ns, e, d; |
1668 |
< |
if (w != null && ctl == c) { |
1669 |
< |
if ((e = (int)c) < 0) |
1670 |
< |
w.qlock = -1; // pool is terminating |
1671 |
< |
else if ((ec = w.eventCount) < 0 && |
1672 |
< |
((d = (int)(c >> AC_SHIFT) + (config & SMASK)) != 0 || |
1673 |
< |
!tryTerminate(false, false))) { |
1674 |
< |
long pc = 0L, parkTime = 0L, deadline = 0L; |
1675 |
< |
if (d == 0 && ec == (e | INT_SIGN) && |
1676 |
< |
(pc = (((long)(w.nextWait & E_MASK)) | |
1677 |
< |
((long)(((int)(c >>> 32)) + UAC_UNIT) << 32))) != 0) { |
1678 |
< |
int dc = -(short)(c >>> TC_SHIFT); |
1679 |
< |
parkTime = (dc < 0 ? FAST_IDLE_TIMEOUT: |
1680 |
< |
(dc + 1) * IDLE_TIMEOUT); |
1681 |
< |
deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP; |
1682 |
< |
} |
1683 |
< |
if ((ns = w.nsteals) != 0) { |
1684 |
< |
long sc = stealCount; |
1685 |
< |
if (U.compareAndSwapLong(this, STEALCOUNT, sc, sc + ns)) |
1686 |
< |
w.nsteals = 0; // collect and rescan |
1687 |
< |
} |
1688 |
< |
else if (w.eventCount < 0 && ctl == c) { |
1689 |
< |
Thread wt = Thread.currentThread(); |
1690 |
< |
Thread.interrupted(); // clear status |
1691 |
< |
U.putObject(wt, PARKBLOCKER, this); |
1692 |
< |
w.parker = wt; // emulate LockSupport.park |
1693 |
< |
if (w.eventCount < 0 && ctl == c) // recheck |
1694 |
< |
U.park(false, parkTime); // block |
1695 |
< |
w.parker = null; |
1696 |
< |
U.putObject(wt, PARKBLOCKER, null); |
1697 |
< |
if (parkTime != 0L && w.eventCount < 0 && ctl == c && |
1698 |
< |
deadline - System.nanoTime() <= 0L && |
1698 |
< |
U.compareAndSwapLong(this, CTL, c, pc)) { |
1699 |
< |
w.eventCount = (w.eventCount + E_SEQ) | E_MASK; |
1700 |
< |
w.qlock = -1; // shrink |
1701 |
< |
} |
1667 |
> |
int ec, ns; |
1668 |
> |
int d = (int)(c >> AC_SHIFT) + (config & SMASK); // 0 if quiescent |
1669 |
> |
if (w != null && (ec = w.eventCount) < 0 && |
1670 |
> |
(d != 0 || !tryTerminate(false, false))) { |
1671 |
> |
long pc = 0L, parkTime = 0L, deadline = 0L; |
1672 |
> |
if (d == 0 && ec == (((int)c) | INT_SIGN) && |
1673 |
> |
(pc = (((long)(w.nextWait & E_MASK)) | |
1674 |
> |
((long)(((int)(c >>> 32)) + UAC_UNIT) << 32))) != 0) { |
1675 |
> |
int dc = -(short)(c >>> TC_SHIFT); |
1676 |
> |
parkTime = (dc < 0 ? FAST_IDLE_TIMEOUT: |
1677 |
> |
(dc + 1) * IDLE_TIMEOUT); |
1678 |
> |
deadline = System.nanoTime() + parkTime - TIMEOUT_SLOP; |
1679 |
> |
} |
1680 |
> |
if ((ns = w.nsteals) != 0) { |
1681 |
> |
long sc = stealCount; |
1682 |
> |
if (U.compareAndSwapLong(this, STEALCOUNT, sc, sc + ns)) |
1683 |
> |
w.nsteals = 0; // collect steals and rescan |
1684 |
> |
} |
1685 |
> |
else if (w.eventCount < 0) { |
1686 |
> |
Thread wt = Thread.currentThread(); |
1687 |
> |
Thread.interrupted(); // clear status |
1688 |
> |
U.putObject(wt, PARKBLOCKER, this); |
1689 |
> |
w.parker = wt; // emulate LockSupport.park |
1690 |
> |
if (w.eventCount < 0) // recheck |
1691 |
> |
U.park(false, parkTime); // block |
1692 |
> |
w.parker = null; |
1693 |
> |
U.putObject(wt, PARKBLOCKER, null); |
1694 |
> |
if (parkTime != 0L && w.eventCount < 0 && ctl == c && |
1695 |
> |
deadline - System.nanoTime() <= 0L && |
1696 |
> |
U.compareAndSwapLong(this, CTL, c, pc)) { |
1697 |
> |
w.eventCount = (w.eventCount + E_SEQ) | E_MASK; |
1698 |
> |
w.qlock = -1; // shrink |
1699 |
|
} |
1700 |
|
} |
1701 |
|
} |