93 |
|
* performs the most common form of parallel invocation: forking a set |
94 |
|
* of tasks and joining them all. |
95 |
|
* |
96 |
< |
* <p>In the most typical usages, a fork-join pair act like a a call |
96 |
> |
* <p>In the most typical usages, a fork-join pair act like a call |
97 |
|
* (fork) and return (join) from a parallel recursive function. As is |
98 |
|
* the case with other forms of recursive calls, returns (joins) |
99 |
|
* should be performed innermost-first. For example, {@code a.fork(); |
143 |
|
* use these {@code protected} methods or marks for any purpose, but |
144 |
|
* they may be of use in the construction of specialized subclasses. |
145 |
|
* For example, parallel graph traversals can use the supplied methods |
146 |
< |
* to avoid revisiting nodes/tasks that have already been |
147 |
< |
* processed. Also, completion based designs can use them to record |
148 |
< |
* that one subtask has completed. (Method names for marking are bulky |
149 |
< |
* in part to encourage definition of methods that reflect their usage |
146 |
> |
* to avoid revisiting nodes/tasks that have already been processed. |
147 |
> |
* Also, completion based designs can use them to record that one |
148 |
> |
* subtask has completed. (Method names for marking are bulky in part |
149 |
> |
* to encourage definition of methods that reflect their usage |
150 |
|
* patterns.) |
151 |
|
* |
152 |
|
* <p>Most base support methods are {@code final}, to prevent |
235 |
|
/** |
236 |
|
* Marks completion and wakes up threads waiting to join this |
237 |
|
* task, also clearing signal request bits. A specialization for |
238 |
< |
* NORMAL completion is in method doExec |
238 |
> |
* NORMAL completion is in method doExec. |
239 |
|
* |
240 |
|
* @param completion one of NORMAL, CANCELLED, EXCEPTIONAL |
241 |
|
* @return completion status on exit |
395 |
|
* @return status upon completion |
396 |
|
*/ |
397 |
|
private int doInvoke() { |
398 |
< |
int s; |
399 |
< |
if ((s = doExec()) < 0) |
400 |
< |
return s; |
401 |
< |
else |
402 |
< |
return doJoin(); |
398 |
> |
int s; Thread t; |
399 |
> |
if ((s = doExec()) >= 0) { |
400 |
> |
if (!((t = Thread.currentThread()) instanceof ForkJoinWorkerThread)) |
401 |
> |
s = externalAwaitDone(); |
402 |
> |
else { |
403 |
> |
ForkJoinWorkerThread wt = (ForkJoinWorkerThread)t; |
404 |
> |
s = awaitJoin(wt.workQueue, wt.pool); |
405 |
> |
} |
406 |
> |
} |
407 |
> |
return s; |
408 |
|
} |
409 |
|
|
410 |
|
// Exception table support |
1075 |
|
* ClassCastException}. |
1076 |
|
*/ |
1077 |
|
public static void helpQuiesce() { |
1078 |
< |
ForkJoinWorkerThread w = |
1078 |
> |
ForkJoinWorkerThread wt = |
1079 |
|
(ForkJoinWorkerThread)Thread.currentThread(); |
1080 |
< |
w.pool.helpQuiescePool(w.workQueue); |
1080 |
> |
wt.pool.helpQuiescePool(wt.workQueue); |
1081 |
|
} |
1082 |
|
|
1083 |
|
/** |
1230 |
|
* have zero queued tasks, so compensate by a factor of |
1231 |
|
* (#idle/#active) threads. |
1232 |
|
*/ |
1233 |
< |
ForkJoinWorkerThread w = |
1233 |
> |
ForkJoinWorkerThread wt = |
1234 |
|
(ForkJoinWorkerThread)Thread.currentThread(); |
1235 |
< |
return w.workQueue.queueSize() - w.pool.idlePerActive(); |
1235 |
> |
return wt.workQueue.queueSize() - wt.pool.idlePerActive(); |
1236 |
|
} |
1237 |
|
|
1238 |
|
// Extension methods |
1330 |
|
* @return a task, or {@code null} if none are available |
1331 |
|
*/ |
1332 |
|
protected static ForkJoinTask<?> pollTask() { |
1333 |
< |
ForkJoinWorkerThread w = |
1333 |
> |
ForkJoinWorkerThread wt = |
1334 |
|
(ForkJoinWorkerThread)Thread.currentThread(); |
1335 |
< |
return w.pool.nextTaskFor(w.workQueue); |
1335 |
> |
return wt.pool.nextTaskFor(wt.workQueue); |
1336 |
|
} |
1337 |
|
|
1338 |
|
// Mark-bit operations |