172 |
|
|
173 |
|
/** |
174 |
|
* Maximum work-stealing queue array size. Must be less than or |
175 |
< |
* equal to 1 << 28 to ensure lack of index wraparound. (This |
176 |
< |
* is less than usual bounds, because we need leftshift by 3 |
177 |
< |
* to be in int range). |
175 |
> |
* equal to 1 << (31 - width of array entry) to ensure lack of |
176 |
> |
* index wraparound. The value is set in the static block |
177 |
> |
* at the end of this file after obtaining width. |
178 |
|
*/ |
179 |
< |
private static final int MAXIMUM_QUEUE_CAPACITY = 1 << 28; |
179 |
> |
private static final int MAXIMUM_QUEUE_CAPACITY; |
180 |
|
|
181 |
|
/** |
182 |
|
* The pool this thread works in. Accessed directly by ForkJoinTask. |
230 |
|
private static final int TRIMMED = 0x08; // killed while suspended |
231 |
|
|
232 |
|
/** |
233 |
< |
* Number of steals, transferred and reset in pool callbacks pool |
234 |
< |
* when idle Accessed directly by pool. |
233 |
> |
* Number of steals. Directly accessed (and reset) by |
234 |
> |
* pool.tryAccumulateStealCount when idle. |
235 |
|
*/ |
236 |
|
int stealCount; |
237 |
|
|
286 |
|
|
287 |
|
/** |
288 |
|
* The task currently being joined, set only when actively trying |
289 |
< |
* to helpStealer. Written only by current thread, but read by |
290 |
< |
* others. |
289 |
> |
* to help other stealers in helpJoinTask. Written only by this |
290 |
> |
* thread, but read by others. |
291 |
|
*/ |
292 |
|
private volatile ForkJoinTask<?> currentJoin; |
293 |
|
|
294 |
|
/** |
295 |
|
* The task most recently stolen from another worker (or |
296 |
< |
* submission queue). Written only by current thread, but read by |
296 |
> |
* submission queue). Written only by this thread, but read by |
297 |
|
* others. |
298 |
|
*/ |
299 |
|
private volatile ForkJoinTask<?> currentSteal; |
313 |
|
} |
314 |
|
|
315 |
|
/** |
316 |
< |
* Performs additional initialization and starts this thread |
316 |
> |
* Performs additional initialization and starts this thread. |
317 |
|
*/ |
318 |
|
final void start(int poolIndex, UncaughtExceptionHandler ueh) { |
319 |
|
this.poolIndex = poolIndex; |
349 |
|
/** |
350 |
|
* Initializes internal state after construction but before |
351 |
|
* processing any tasks. If you override this method, you must |
352 |
< |
* invoke super.onStart() at the beginning of the method. |
352 |
> |
* invoke @code{super.onStart()} at the beginning of the method. |
353 |
|
* Initialization requires care: Most fields must have legal |
354 |
|
* default values, to ensure that attempted accesses from other |
355 |
|
* threads work correctly even before this thread starts |
381 |
|
if (active) { |
382 |
|
int a; // inline p.tryDecrementActiveCount |
383 |
|
active = false; |
384 |
< |
do {} while(!UNSAFE.compareAndSwapInt |
385 |
< |
(p, poolRunStateOffset, a = p.runState, a - 1)); |
384 |
> |
do {} while (!UNSAFE.compareAndSwapInt |
385 |
> |
(p, poolRunStateOffset, a = p.runState, a - 1)); |
386 |
|
} |
387 |
|
cancelTasks(); |
388 |
|
setTerminated(); |
416 |
|
// helpers for run() |
417 |
|
|
418 |
|
/** |
419 |
< |
* Find and execute tasks and check status while running |
419 |
> |
* Finds and executes tasks, and checks status while running. |
420 |
|
*/ |
421 |
|
private void mainLoop() { |
422 |
|
boolean ran = false; // true if ran a task on last step |
430 |
|
} |
431 |
|
|
432 |
|
/** |
433 |
< |
* Try to steal a task and execute it |
433 |
> |
* Tries to steal a task and execute it. |
434 |
|
* |
435 |
|
* @return true if ran a task |
436 |
|
*/ |
447 |
|
} |
448 |
|
|
449 |
|
/** |
450 |
< |
* If a submission exists, try to activate and run it; |
450 |
> |
* If a submission exists, try to activate and run it. |
451 |
|
* |
452 |
|
* @return true if ran a task |
453 |
|
*/ |
454 |
|
private boolean tryExecSubmission() { |
455 |
|
ForkJoinPool p = pool; |
456 |
+ |
// This loop is needed in case attempt to activate fails, in |
457 |
+ |
// which case we only retry if there still appears to be a |
458 |
+ |
// submission. |
459 |
|
while (p.hasQueuedSubmissions()) { |
460 |
|
ForkJoinTask<?> t; int a; |
461 |
|
if (active || // inline p.tryIncrementActiveCount |
480 |
|
*/ |
481 |
|
private void execLocalTasks() { |
482 |
|
while (runState == 0) { |
483 |
< |
ForkJoinTask<?> t = locallyFifo? locallyDeqTask() : popTask(); |
483 |
> |
ForkJoinTask<?> t = locallyFifo ? locallyDeqTask() : popTask(); |
484 |
|
if (t != null) |
485 |
|
t.quietlyExec(); |
486 |
|
else if (sp == base) |
490 |
|
|
491 |
|
/* |
492 |
|
* Intrinsics-based atomic writes for queue slots. These are |
493 |
< |
* basically the same as methods in AtomicObjectArray, but |
493 |
> |
* basically the same as methods in AtomicReferenceArray, but |
494 |
|
* specialized for (1) ForkJoinTask elements (2) requirement that |
495 |
|
* nullness and bounds checks have already been performed by |
496 |
|
* callers and (3) effective offsets are known not to overflow |
497 |
|
* from int to long (because of MAXIMUM_QUEUE_CAPACITY). We don't |
498 |
|
* need corresponding version for reads: plain array reads are OK |
499 |
< |
* because they protected by other volatile reads and are |
499 |
> |
* because they are protected by other volatile reads and are |
500 |
|
* confirmed by CASes. |
501 |
|
* |
502 |
|
* Most uses don't actually call these methods, but instead contain |
520 |
|
* range. This method is used only during resets and backouts. |
521 |
|
*/ |
522 |
|
private static final void writeSlot(ForkJoinTask<?>[] q, int i, |
523 |
< |
ForkJoinTask<?> t) { |
523 |
> |
ForkJoinTask<?> t) { |
524 |
|
UNSAFE.putObjectVolatile(q, (i << qShift) + qBase, t); |
525 |
|
} |
526 |
|
|
565 |
|
|
566 |
|
/** |
567 |
|
* Tries to take a task from the base of own queue. Assumes active |
568 |
< |
* status. Called only by current thread. |
568 |
> |
* status. Called only by this thread. |
569 |
|
* |
570 |
|
* @return a task, or null if none |
571 |
|
*/ |
588 |
|
|
589 |
|
/** |
590 |
|
* Returns a popped task, or null if empty. Assumes active status. |
591 |
< |
* Called only by current thread. |
591 |
> |
* Called only by this thread. |
592 |
|
*/ |
593 |
|
private ForkJoinTask<?> popTask() { |
594 |
|
ForkJoinTask<?>[] q = queue; |
612 |
|
|
613 |
|
/** |
614 |
|
* Specialized version of popTask to pop only if topmost element |
615 |
< |
* is the given task. Called only by current thread while |
613 |
< |
* active. |
615 |
> |
* is the given task. Called only by this thread while active. |
616 |
|
* |
617 |
|
* @param t the task. Caller must ensure non-null. |
618 |
|
*/ |
630 |
|
} |
631 |
|
|
632 |
|
/** |
633 |
< |
* Returns next task or null if empty or contended |
633 |
> |
* Returns next task, or null if empty or contended. |
634 |
|
*/ |
635 |
|
final ForkJoinTask<?> peekTask() { |
636 |
|
ForkJoinTask<?>[] q = queue; |
672 |
|
* Computes next value for random victim probe in scan(). Scans |
673 |
|
* don't require a very high quality generator, but also not a |
674 |
|
* crummy one. Marsaglia xor-shift is cheap and works well enough. |
675 |
< |
* Note: This is manually inlined in scan() |
675 |
> |
* Note: This is manually inlined in scan(). |
676 |
|
*/ |
677 |
|
private static final int xorShift(int r) { |
678 |
|
r ^= r << 13; |
778 |
|
} |
779 |
|
|
780 |
|
/** |
781 |
< |
* Sets state to TERMINATED. Called only by onTermination() |
781 |
> |
* Sets state to TERMINATED. Called only by onTermination(). |
782 |
|
*/ |
783 |
|
private void setTerminated() { |
784 |
|
int s; |
899 |
|
if (active || |
900 |
|
(active = UNSAFE.compareAndSwapInt(p, poolRunStateOffset, |
901 |
|
a = p.runState, a + 1))) |
902 |
< |
return locallyFifo? locallyDeqTask() : popTask(); |
902 |
> |
return locallyFifo ? locallyDeqTask() : popTask(); |
903 |
|
} |
904 |
|
return null; |
905 |
|
} |
1057 |
|
} |
1058 |
|
|
1059 |
|
/** |
1060 |
+ |
* Implements ForkJoinTask.getSurplusQueuedTaskCount(). |
1061 |
|
* Returns an estimate of the number of tasks, offset by a |
1062 |
|
* function of number of idle workers. |
1063 |
|
* |
1129 |
|
} |
1130 |
|
if (p.isQuiescent()) { |
1131 |
|
active = true; // re-activate |
1132 |
< |
do {} while(!UNSAFE.compareAndSwapInt |
1133 |
< |
(p, poolRunStateOffset, a = p.runState, a+1)); |
1132 |
> |
do {} while (!UNSAFE.compareAndSwapInt |
1133 |
> |
(p, poolRunStateOffset, a = p.runState, a+1)); |
1134 |
|
return; |
1135 |
|
} |
1136 |
|
} |
1160 |
|
if ((s & (s-1)) != 0) |
1161 |
|
throw new Error("data type scale not a power of two"); |
1162 |
|
qShift = 31 - Integer.numberOfLeadingZeros(s); |
1163 |
+ |
MAXIMUM_QUEUE_CAPACITY = 1 << (31 - qShift); |
1164 |
|
} |
1165 |
|
|
1166 |
|
private static long objectFieldOffset(String field, Class<?> klazz) { |