496 |
|
*/ |
497 |
|
private volatile long eventWaiters; |
498 |
|
|
499 |
< |
private static final int EVENT_COUNT_SHIFT = 32; |
500 |
< |
private static final long WAITER_ID_MASK = (1L << 16) - 1L; |
499 |
> |
private static final int EVENT_COUNT_SHIFT = 32; |
500 |
> |
private static final int WAITER_ID_MASK = (1 << 16) - 1; |
501 |
|
|
502 |
|
/** |
503 |
|
* A counter for events that may wake up worker threads: |
586 |
|
// are usually manually inlined by callers |
587 |
|
|
588 |
|
/** |
589 |
< |
* Increments running count part of workerCounts |
589 |
> |
* Increments running count part of workerCounts. |
590 |
|
*/ |
591 |
|
final void incrementRunningCount() { |
592 |
|
int c; |
596 |
|
} |
597 |
|
|
598 |
|
/** |
599 |
< |
* Tries to increment running count part of workerCounts |
599 |
> |
* Tries to increment running count part of workerCounts. |
600 |
|
*/ |
601 |
|
final boolean tryIncrementRunningCount() { |
602 |
|
int c; |
606 |
|
} |
607 |
|
|
608 |
|
/** |
609 |
< |
* Tries to decrement running count unless already zero |
609 |
> |
* Tries to decrement running count unless already zero. |
610 |
|
*/ |
611 |
|
final boolean tryDecrementRunningCount() { |
612 |
|
int wc = workerCounts; |
728 |
|
* Releases workers blocked on a count not equal to current count. |
729 |
|
* Normally called after precheck that eventWaiters isn't zero to |
730 |
|
* avoid wasted array checks. Gives up upon a change in count or |
731 |
< |
* upon releasing two workers, letting others take over. |
731 |
> |
* upon releasing four workers, letting others take over. |
732 |
|
*/ |
733 |
|
private void releaseEventWaiters() { |
734 |
|
ForkJoinWorkerThread[] ws = workers; |
735 |
|
int n = ws.length; |
736 |
|
long h = eventWaiters; |
737 |
|
int ec = eventCount; |
738 |
< |
boolean releasedOne = false; |
738 |
> |
int releases = 4; |
739 |
|
ForkJoinWorkerThread w; int id; |
740 |
< |
while ((id = ((int)(h & WAITER_ID_MASK)) - 1) >= 0 && |
740 |
> |
while ((id = (((int)h) & WAITER_ID_MASK) - 1) >= 0 && |
741 |
|
(int)(h >>> EVENT_COUNT_SHIFT) != ec && |
742 |
|
id < n && (w = ws[id]) != null) { |
743 |
|
if (UNSAFE.compareAndSwapLong(this, eventWaitersOffset, |
744 |
|
h, w.nextWaiter)) { |
745 |
|
LockSupport.unpark(w); |
746 |
< |
if (releasedOne) // exit on second release |
746 |
> |
if (--releases == 0) |
747 |
|
break; |
748 |
– |
releasedOne = true; |
748 |
|
} |
749 |
|
if (eventCount != ec) |
750 |
|
break; |
774 |
|
long nh = (((long)ec) << EVENT_COUNT_SHIFT) | ((long)(w.poolIndex+1)); |
775 |
|
long h; |
776 |
|
while ((runState < SHUTDOWN || !tryTerminate(false)) && |
777 |
< |
(((int)((h = eventWaiters) & WAITER_ID_MASK)) == 0 || |
777 |
> |
(((int)(h = eventWaiters) & WAITER_ID_MASK) == 0 || |
778 |
|
(int)(h >>> EVENT_COUNT_SHIFT) == ec) && |
779 |
|
eventCount == ec) { |
780 |
|
if (UNSAFE.compareAndSwapLong(this, eventWaitersOffset, |
933 |
|
} |
934 |
|
else if ((h = eventWaiters) != 0L) { |
935 |
|
long nh; |
936 |
< |
int id = ((int)(h & WAITER_ID_MASK)) - 1; |
936 |
> |
int id = (((int)h) & WAITER_ID_MASK) - 1; |
937 |
|
if (id >= 0 && id < n && (w = ws[id]) != null && |
938 |
|
(nh = w.nextWaiter) != 0L && // keep at least one worker |
939 |
|
UNSAFE.compareAndSwapLong(this, eventWaitersOffset, h, nh)) |
1057 |
|
long h = eventWaiters; |
1058 |
|
if (h != 0L && (int)(h >>> EVENT_COUNT_SHIFT) != eventCount) |
1059 |
|
releaseEventWaiters(); |
1061 |
– |
if (joinMe.status < 0) |
1062 |
– |
break; |
1060 |
|
if ((workerCounts & RUNNING_COUNT_MASK) != 0) { |
1061 |
|
long ms; int ns; |
1062 |
|
if (!timed) { |
1075 |
|
else |
1076 |
|
ns = (int) (nt % 1000000); |
1077 |
|
} |
1078 |
< |
if (joinMe.internalAwaitDone(ms, ns) < 0) |
1082 |
< |
break; |
1078 |
> |
joinMe.internalAwaitDone(ms, ns); |
1079 |
|
} |
1080 |
+ |
if (joinMe.status < 0) |
1081 |
+ |
break; |
1082 |
|
} |
1083 |
|
helpMaintainParallelism(); |
1084 |
|
} |
1773 |
|
* commenced but not yet completed. This method may be useful for |
1774 |
|
* debugging. A return of {@code true} reported a sufficient |
1775 |
|
* period after shutdown may indicate that submitted tasks have |
1776 |
< |
* ignored or suppressed interruption, causing this executor not |
1777 |
< |
* to properly terminate. |
1776 |
> |
* ignored or suppressed interruption, or are waiting for IO, |
1777 |
> |
* causing this executor not to properly terminate. (See the |
1778 |
> |
* advisory notes for class {@link ForkJoinTask} stating that |
1779 |
> |
* tasks should not normally entail blocking operations. But if |
1780 |
> |
* they do, they must abort them on interrupt.) |
1781 |
|
* |
1782 |
|
* @return {@code true} if terminating but not yet terminated |
1783 |
|
*/ |