1691 |
|
* Returns true if all workers are busy, possibly creating one if allowed |
1692 |
|
*/ |
1693 |
|
final boolean isSaturated() { |
1694 |
< |
int maxTotal = bounds >>> SWIDTH; |
1694 |
> |
int par = mode & SMASK, maxTotal = bounds >>> SWIDTH; |
1695 |
|
for (long c;;) { |
1696 |
|
if (((int)(c = ctl) & ~UNSIGNALLED) != 0) |
1697 |
|
return false; |
1698 |
< |
if ((short)(c >>> TC_SHIFT) >= maxTotal) |
1699 |
< |
return true; |
1698 |
> |
if ((short)(c >>> TC_SHIFT) >= maxTotal || par == 0) |
1699 |
> |
return true; // cannot create |
1700 |
|
long nc = ((c + TC_UNIT) & TC_MASK) | (c & ~TC_MASK); |
1701 |
|
if (compareAndSetCtl(c, nc)) |
1702 |
|
return !createWorker(); |
1742 |
|
*/ |
1743 |
|
private int tryCompensate(long c) { |
1744 |
|
Predicate<? super ForkJoinPool> sat; |
1745 |
< |
int b = bounds; // counts are signed; centered at parallelism level == 0 |
1745 |
> |
int md = mode, b = bounds; |
1746 |
> |
// counts are signed; centered at parallelism level == 0 |
1747 |
|
int minActive = (short)(b & SMASK), |
1748 |
|
maxTotal = b >>> SWIDTH, |
1749 |
|
active = (int)(c >> RC_SHIFT), |
1750 |
|
total = (short)(c >>> TC_SHIFT), |
1751 |
|
sp = (int)c & ~UNSIGNALLED; |
1752 |
< |
if (total >= 0) { |
1752 |
> |
if ((md & SMASK) == 0) |
1753 |
> |
return 0; // cannot compensate if parallelism zero |
1754 |
> |
else if (total >= 0) { |
1755 |
|
if (sp != 0) { // activate idle worker |
1756 |
|
WorkQueue[] qs; int n; WorkQueue v; |
1757 |
|
if ((qs = queues) != null && (n = qs.length) > 0 && |
2520 |
|
} catch (Exception ignore) { |
2521 |
|
} |
2522 |
|
int p = this.mode = Math.min(Math.max(parallelism, 0), MAX_CAP); |
2523 |
+ |
int maxSpares = (p == 0) ? 0 : COMMON_MAX_SPARES; |
2524 |
+ |
int bnds = ((1 - p) & SMASK) | (maxSpares << SWIDTH); |
2525 |
|
int size = 1 << (33 - Integer.numberOfLeadingZeros(p > 0 ? p - 1 : 1)); |
2526 |
|
this.factory = (fac != null) ? fac : |
2527 |
|
new DefaultCommonPoolForkJoinWorkerThreadFactory(); |
2529 |
|
this.keepAlive = DEFAULT_KEEPALIVE; |
2530 |
|
this.saturate = null; |
2531 |
|
this.workerNamePrefix = null; |
2532 |
< |
this.bounds = ((1 - p) & SMASK) | (COMMON_MAX_SPARES << SWIDTH); |
2532 |
> |
this.bounds = bnds; |
2533 |
|
this.ctl = ((((long)(-p) << TC_SHIFT) & TC_MASK) | |
2534 |
|
(((long)(-p) << RC_SHIFT) & RC_MASK)); |
2535 |
|
this.queues = new WorkQueue[size]; |