@@ -1273,15 +1273,17 @@ final int queueSize() {
1273
1273
/**
1274
1274
* Pushes a task. Called only by owner or if already locked
1275
1275
*
1276
- * @param task the task. Caller must ensure non- null.
1276
+ * @param task the task; no-op if null
1277
1277
* @param pool the pool to signal if was previously empty, else null
1278
1278
* @param internal if caller owns this queue
1279
1279
* @throws RejectedExecutionException if array could not be resized
1280
1280
*/
1281
1281
final void push (ForkJoinTask <?> task , ForkJoinPool pool ,
1282
1282
boolean internal ) {
1283
1283
int s = top , b = base , m , cap , room ; ForkJoinTask <?>[] a ;
1284
- if ((a = array ) != null && (cap = a .length ) > 0 ) { // else disabled
1284
+ if ((a = array ) != null && (cap = a .length ) > 0 && // else disabled
1285
+ task != null ) {
1286
+ int pk = task .noUserHelp () + 1 ; // prev slot offset
1285
1287
if ((room = (m = cap - 1 ) - (s - b )) >= 0 ) {
1286
1288
top = s + 1 ;
1287
1289
long pos = slotOffset (m & s );
@@ -1296,9 +1298,7 @@ final void push(ForkJoinTask<?> task, ForkJoinPool pool,
1296
1298
unlockPhase ();
1297
1299
if (room < 0 )
1298
1300
throw new RejectedExecutionException ("Queue capacity exceeded" );
1299
- if ((room == 0 || // pad if no caller-run
1300
- a [m & (s - ((internal || task == null ||
1301
- task .noUserHelp () == 0 ) ? 1 : 2 ))] == null ) &&
1301
+ if ((room == 0 || a [m & (s - pk )] == null ) &&
1302
1302
pool != null )
1303
1303
pool .signalWork (); // may have appeared empty
1304
1304
}
@@ -2016,14 +2016,13 @@ final void runWorker(WorkQueue w) {
2016
2016
}
2017
2017
else {
2018
2018
boolean propagate ;
2019
- int nb = q .base = b + 1 ;
2019
+ int nb = q .base = b + 1 , prevSrc = src ;
2020
2020
w .nsteals = ++nsteals ;
2021
- int ts = t .status ;
2022
- w .source = j ; // volatile
2021
+ w .source = src = j ; // volatile
2023
2022
rescan = true ;
2023
+ int nh = t .noUserHelp ();
2024
2024
if (propagate =
2025
- ((src != (src = j ) || t .noUserHelp () != 0 ) &&
2026
- a [nb & m ] != null ))
2025
+ (prevSrc != src || nh != 0 ) && a [nb & m ] != null )
2027
2026
signalWork ();
2028
2027
w .topLevelExec (t , fifo );
2029
2028
if ((b = q .base ) != nb && !propagate )
@@ -2062,8 +2061,8 @@ private int deactivate(WorkQueue w, int phase) {
2062
2061
((e & SHUTDOWN ) != 0L && ac == 0 && quiescent () > 0 ) ||
2063
2062
(qs = queues ) == null || (n = qs .length ) <= 0 )
2064
2063
return IDLE ; // terminating
2065
- int prechecks = 3 ; // reactivation threshold
2066
- for (int k = Math . max ( n << 2 , SPIN_WAITS << 1 ) ;;) {
2064
+ int k = Math . max ( n << 2 , SPIN_WAITS << 1 );
2065
+ for (int prechecks = k / n ;;) { // reactivation threshold
2067
2066
WorkQueue q ; int cap ; ForkJoinTask <?>[] a ; long c ;
2068
2067
if (w .phase == activePhase )
2069
2068
return activePhase ;
@@ -2072,7 +2071,7 @@ private int deactivate(WorkQueue w, int phase) {
2072
2071
if ((q = qs [k & (n - 1 )]) == null )
2073
2072
Thread .onSpinWait ();
2074
2073
else if ((a = q .array ) != null && (cap = a .length ) > 0 &&
2075
- a [q .base & (cap - 1 )] != null && --prechecks < 0 &&
2074
+ a [q .base & (cap - 1 )] != null && --prechecks <= 0 &&
2076
2075
(int )(c = ctl ) == activePhase &&
2077
2076
compareAndSetCtl (c , (sp & LMASK ) | ((c + RC_UNIT ) & UMASK )))
2078
2077
return w .phase = activePhase ; // reactivate
0 commit comments