691 |
|
|
692 |
|
/** |
693 |
|
* Takes next task, if one exists, in LIFO order. Call only |
694 |
< |
* by owner in unshared queues. (We do not have a shared |
695 |
< |
* version of this method because it is never needed.) |
694 |
> |
* by owner in unshared queues. |
695 |
|
*/ |
696 |
|
final ForkJoinTask<?> pop() { |
697 |
|
ForkJoinTask<?>[] a; ForkJoinTask<?> t; int m; |
709 |
|
return null; |
710 |
|
} |
711 |
|
|
712 |
+ |
final ForkJoinTask<?> sharedPop() { |
713 |
+ |
ForkJoinTask<?> task = null; |
714 |
+ |
if (runState == 0 && U.compareAndSwapInt(this, RUNSTATE, 0, 1)) { |
715 |
+ |
try { |
716 |
+ |
ForkJoinTask<?>[] a; int m; |
717 |
+ |
if ((a = array) != null && (m = a.length - 1) >= 0) { |
718 |
+ |
for (int s; (s = top - 1) - base >= 0;) { |
719 |
+ |
long j = ((m & s) << ASHIFT) + ABASE; |
720 |
+ |
ForkJoinTask<?> t = |
721 |
+ |
(ForkJoinTask<?>)U.getObject(a, j); |
722 |
+ |
if (t == null) |
723 |
+ |
break; |
724 |
+ |
if (U.compareAndSwapObject(a, j, t, null)) { |
725 |
+ |
top = s; |
726 |
+ |
task = t; |
727 |
+ |
break; |
728 |
+ |
} |
729 |
+ |
} |
730 |
+ |
} |
731 |
+ |
} finally { |
732 |
+ |
runState = 0; |
733 |
+ |
} |
734 |
+ |
} |
735 |
+ |
return task; |
736 |
+ |
} |
737 |
+ |
|
738 |
+ |
|
739 |
|
/** |
740 |
|
* Takes a task in FIFO order if b is base of queue and a task |
741 |
|
* can be claimed without contention. Specialized versions |
909 |
|
return seed = r ^= r << 5; |
910 |
|
} |
911 |
|
|
912 |
< |
// Execution methods |
912 |
> |
// Specialized execution methods |
913 |
|
|
914 |
|
/** |
915 |
|
* Pops and runs tasks until empty. |
988 |
|
} |
989 |
|
|
990 |
|
/** |
991 |
+ |
* Version of shared pop that takes top element only if it |
992 |
+ |
* its root is the given CountedCompleter. |
993 |
+ |
*/ |
994 |
+ |
final CountedCompleter<?> sharedPopCC(CountedCompleter<?> root) { |
995 |
+ |
CountedCompleter<?> task = null; |
996 |
+ |
if (runState == 0 && U.compareAndSwapInt(this, RUNSTATE, 0, 1)) { |
997 |
+ |
try { |
998 |
+ |
ForkJoinTask<?>[] a; int m; |
999 |
+ |
if ((a = array) != null && (m = a.length - 1) >= 0) { |
1000 |
+ |
outer:for (int s; (s = top - 1) - base >= 0;) { |
1001 |
+ |
long j = ((m & s) << ASHIFT) + ABASE; |
1002 |
+ |
ForkJoinTask<?> t = |
1003 |
+ |
(ForkJoinTask<?>)U.getObject(a, j); |
1004 |
+ |
if (t == null || !(t instanceof CountedCompleter)) |
1005 |
+ |
break; |
1006 |
+ |
CountedCompleter<?> cc = (CountedCompleter<?>)t; |
1007 |
+ |
for (CountedCompleter<?> q = cc, p;;) { |
1008 |
+ |
if (q == root) { |
1009 |
+ |
if (U.compareAndSwapObject(a, j, cc, null)) { |
1010 |
+ |
top = s; |
1011 |
+ |
task = cc; |
1012 |
+ |
break outer; |
1013 |
+ |
} |
1014 |
+ |
break; |
1015 |
+ |
} |
1016 |
+ |
if ((p = q.completer) == null) |
1017 |
+ |
break outer; |
1018 |
+ |
q = p; |
1019 |
+ |
} |
1020 |
+ |
} |
1021 |
+ |
} |
1022 |
+ |
} finally { |
1023 |
+ |
runState = 0; |
1024 |
+ |
} |
1025 |
+ |
} |
1026 |
+ |
return task; |
1027 |
+ |
} |
1028 |
+ |
|
1029 |
+ |
/** |
1030 |
|
* Executes a top-level task and any local tasks remaining |
1031 |
|
* after execution. |
1032 |
|
*/ |
1147 |
|
public static final ForkJoinWorkerThreadFactory |
1148 |
|
defaultForkJoinWorkerThreadFactory; |
1149 |
|
|
1085 |
– |
|
1150 |
|
/** Property prefix for constructing common pool */ |
1151 |
|
private static final String propPrefix = |
1152 |
|
"java.util.concurrent.ForkJoinPool.common."; |
1360 |
|
try { |
1361 |
|
wait(); |
1362 |
|
} catch (InterruptedException ie) { |
1363 |
< |
Thread.currentThread().interrupt(); |
1363 |
> |
try { |
1364 |
> |
Thread.currentThread().interrupt(); |
1365 |
> |
} catch (SecurityException ignore) { |
1366 |
> |
} |
1367 |
|
} |
1368 |
|
} |
1369 |
|
else |
1401 |
|
*/ |
1402 |
|
final String nextWorkerName() { |
1403 |
|
int n; |
1404 |
< |
do {} while(!U.compareAndSwapInt(this, NEXTWORKERNUMBER, |
1405 |
< |
n = nextWorkerNumber, ++n)); |
1404 |
> |
do {} while (!U.compareAndSwapInt(this, NEXTWORKERNUMBER, |
1405 |
> |
n = nextWorkerNumber, ++n)); |
1406 |
|
return workerNamePrefix.concat(Integer.toString(n)); |
1407 |
|
} |
1408 |
|
|
1448 |
|
synchronized (this) { notifyAll(); }; |
1449 |
|
} |
1450 |
|
} |
1384 |
– |
|
1451 |
|
} |
1452 |
|
|
1453 |
|
/** |
1464 |
|
if (wt != null && (w = wt.workQueue) != null) { |
1465 |
|
w.runState = -1; // ensure runState is set |
1466 |
|
long steals = w.totalSteals + w.nsteals, sc; |
1467 |
< |
do {} while(!U.compareAndSwapLong(this, STEALCOUNT, |
1468 |
< |
sc = stealCount, sc + steals)); |
1467 |
> |
do {} while (!U.compareAndSwapLong(this, STEALCOUNT, |
1468 |
> |
sc = stealCount, sc + steals)); |
1469 |
|
int idx = w.poolIndex; |
1470 |
|
while (!U.compareAndSwapInt(this, MAINLOCK, 0, 1)) |
1471 |
|
tryAwaitMainLock(); |
1496 |
|
} |
1497 |
|
|
1498 |
|
if (ex != null) // rethrow |
1499 |
< |
U.throwException(ex); |
1499 |
> |
ForkJoinTask.rethrow(ex); |
1500 |
|
} |
1501 |
|
|
1502 |
|
// Submissions |
1582 |
|
* @return true if successful |
1583 |
|
*/ |
1584 |
|
static boolean tryUnsubmitFromCommonPool(ForkJoinTask<?> task) { |
1585 |
< |
// Peek, looking for task and eligibility before |
1586 |
< |
// using trySharedUnpush to actually take it under lock |
1587 |
< |
ForkJoinPool p; WorkQueue[] ws; WorkQueue q; |
1588 |
< |
ForkJoinTask<?>[] a; int t, s, n; |
1589 |
< |
int k = submitters.get().seed & SQMASK; |
1590 |
< |
return ((p = commonPool) != null && |
1591 |
< |
(ws = p.workQueues) != null && |
1592 |
< |
ws.length > (k &= p.submitMask) && |
1593 |
< |
(q = ws[k]) != null && |
1594 |
< |
(a = q.array) != null && |
1595 |
< |
(n = (t = q.top) - q.base) > 0 && |
1596 |
< |
(n > 1 || (int)(p.ctl >> AC_SHIFT) < 0) && |
1597 |
< |
(s = t - 1) >= 0 && s < a.length && a[s] == task && |
1598 |
< |
q.trySharedUnpush(task)); |
1585 |
> |
// If not oversaturating platform, peek, looking for task and |
1586 |
> |
// eligibility before using trySharedUnpush to actually take |
1587 |
> |
// it under lock |
1588 |
> |
ForkJoinPool p; WorkQueue[] ws; WorkQueue w, q; |
1589 |
> |
ForkJoinTask<?>[] a; int ac, s, m; |
1590 |
> |
if ((p = commonPool) != null && (ws = p.workQueues) != null) { |
1591 |
> |
int k = submitters.get().seed & p.submitMask & SQMASK; |
1592 |
> |
if ((m = ws.length - 1) >= k && (q = ws[k]) != null && |
1593 |
> |
(ac = (int)(p.ctl >> AC_SHIFT)) <= 0) { |
1594 |
> |
if (ac == 0) { // double check if all workers active |
1595 |
> |
for (int i = 1; i <= m; i += 2) { |
1596 |
> |
if ((w = ws[i]) != null && w.parker != null) { |
1597 |
> |
ac = -1; |
1598 |
> |
break; |
1599 |
> |
} |
1600 |
> |
} |
1601 |
> |
} |
1602 |
> |
return (ac < 0 && (a = q.array) != null && |
1603 |
> |
(s = q.top - 1) - q.base >= 0 && |
1604 |
> |
s >= 0 && s < a.length && |
1605 |
> |
a[s] == task && |
1606 |
> |
q.trySharedUnpush(task)); |
1607 |
> |
} |
1608 |
> |
} |
1609 |
> |
return false; |
1610 |
> |
} |
1611 |
> |
|
1612 |
> |
/** |
1613 |
> |
* Tries to pop and run a task within same computation from common pool |
1614 |
> |
*/ |
1615 |
> |
static void popAndExecCCFromCommonPool(CountedCompleter<?> cc) { |
1616 |
> |
ForkJoinPool p; WorkQueue[] ws; WorkQueue q, w; int m, ac; |
1617 |
> |
CountedCompleter<?> par, task; |
1618 |
> |
if ((p = commonPool) != null && (ws = p.workQueues) != null) { |
1619 |
> |
while ((par = cc.completer) != null) // find root |
1620 |
> |
cc = par; |
1621 |
> |
int k = submitters.get().seed & p.submitMask & SQMASK; |
1622 |
> |
if ((m = ws.length - 1) >= k && (q = ws[k]) != null && |
1623 |
> |
(ac = (int)(p.ctl >> AC_SHIFT)) <= 0) { |
1624 |
> |
if (ac == 0) { |
1625 |
> |
for (int i = 1; i <= m; i += 2) { |
1626 |
> |
if ((w = ws[i]) != null && w.parker != null) { |
1627 |
> |
ac = -1; |
1628 |
> |
break; |
1629 |
> |
} |
1630 |
> |
} |
1631 |
> |
} |
1632 |
> |
if (ac < 0 && q.top - q.base > 0 && |
1633 |
> |
(task = q.sharedPopCC(cc)) != null) |
1634 |
> |
task.exec(); |
1635 |
> |
} |
1636 |
> |
} |
1637 |
|
} |
1638 |
|
|
1639 |
|
// Maintaining ctl counts |
2171 |
|
* Restricted version of helpQuiescePool for non-FJ callers |
2172 |
|
*/ |
2173 |
|
static void externalHelpQuiescePool() { |
2174 |
< |
ForkJoinPool p; WorkQueue[] ws; WorkQueue w, q; |
2175 |
< |
ForkJoinTask<?> t; int b; |
2174 |
> |
ForkJoinPool p; WorkQueue[] ws; WorkQueue q, sq; |
2175 |
> |
ForkJoinTask<?>[] a; int b; |
2176 |
> |
ForkJoinTask<?> t = null; |
2177 |
|
int k = submitters.get().seed & SQMASK; |
2178 |
|
if ((p = commonPool) != null && |
2179 |
|
(ws = p.workQueues) != null && |
2180 |
|
ws.length > (k &= p.submitMask) && |
2181 |
< |
(w = ws[k]) != null && |
2182 |
< |
(q = p.findNonEmptyStealQueue(w)) != null && |
2183 |
< |
(b = q.base) - q.top < 0 && |
2184 |
< |
(t = q.pollAt(b)) != null) |
2185 |
< |
t.doExec(); |
2181 |
> |
(q = ws[k]) != null) { |
2182 |
> |
while (q.top - q.base > 0) { |
2183 |
> |
if ((t = q.sharedPop()) != null) |
2184 |
> |
break; |
2185 |
> |
} |
2186 |
> |
if (t == null && (sq = p.findNonEmptyStealQueue(q)) != null && |
2187 |
> |
(b = sq.base) - sq.top < 0) |
2188 |
> |
t = sq.pollAt(b); |
2189 |
> |
if (t != null) |
2190 |
> |
t.doExec(); |
2191 |
> |
} |
2192 |
|
} |
2193 |
|
|
2194 |
|
/** |
2230 |
|
static int getEstimatedSubmitterQueueLength() { |
2231 |
|
ForkJoinPool p; WorkQueue[] ws; WorkQueue q; |
2232 |
|
int k = submitters.get().seed & SQMASK; |
2233 |
< |
return ((p = commonPool) != null && |
2123 |
< |
p.runState >= 0 && |
2124 |
< |
(ws = p.workQueues) != null && |
2233 |
> |
return ((p = commonPool) != null && (ws = p.workQueues) != null && |
2234 |
|
ws.length > (k &= p.submitMask) && |
2235 |
|
(q = ws[k]) != null) ? |
2236 |
|
q.queueSize() : 0; |
2256 |
|
for (long c;;) { |
2257 |
|
if (((c = ctl) & STOP_BIT) != 0) { // already terminating |
2258 |
|
if ((short)(c >>> TC_SHIFT) == -parallelism) { |
2259 |
< |
synchronized(this) { |
2259 |
> |
synchronized (this) { |
2260 |
|
notifyAll(); // signal when 0 workers |
2261 |
|
} |
2262 |
|
} |
2980 |
|
return true; |
2981 |
|
long startTime = System.nanoTime(); |
2982 |
|
boolean terminated = false; |
2983 |
< |
synchronized(this) { |
2983 |
> |
synchronized (this) { |
2984 |
|
for (long waitTime = nanos, millis = 0L;;) { |
2985 |
|
if (terminated = isTerminated() || |
2986 |
|
waitTime <= 0L || |
3165 |
|
defaultForkJoinWorkerThreadFactory : |
3166 |
|
((ForkJoinWorkerThreadFactory)ClassLoader. |
3167 |
|
getSystemClassLoader().loadClass(fp).newInstance()); |
3168 |
< |
Thread.UncaughtExceptionHandler ueh = (up == null)? null : |
3168 |
> |
Thread.UncaughtExceptionHandler ueh = (up == null) ? null : |
3169 |
|
((Thread.UncaughtExceptionHandler)ClassLoader. |
3170 |
|
getSystemClassLoader().loadClass(up).newInstance()); |
3171 |
|
int par; |