@@ -610,12 +610,11 @@ public class ForkJoinPool extends AbstractExecutorService {
610
610
* it tries to deactivate()), giving up (and rescanning) on "ctl"
611
611
* contention. To avoid missed signals during deactivation, the
612
612
* method rescans and reactivates if there may have been a missed
613
- * (external) signal during deactivation. To reduce false-alarm
614
- * reactivations while doing so, we scan multiple times
615
- * (analogously to method quiescent()) before trying to
616
- * reactivate. Because idle workers are often not yet blocked
617
- * (parked), we use a WorkQueue field to advertise that a waiter
618
- * actually needs unparking upon signal.
613
+ * signal during deactivation. To reduce false-alarm reactivations
614
+ * while doing so, we scan multiple times (analogously to method
615
+ * quiescent()) before trying to reactivate. Because idle workers
616
+ * are often not yet blocked (parked), we use a WorkQueue field to
617
+ * advertise that a waiter actually needs unparking upon signal.
619
618
*
620
619
* Quiescence. Workers scan looking for work, giving up when they
621
620
* don't find any, without being sure that none are available.
@@ -1996,7 +1995,7 @@ private int deactivate(WorkQueue w, int phase) {
1996
1995
return IDLE ;
1997
1996
int p = phase | IDLE , activePhase = phase + (IDLE << 1 );
1998
1997
long pc = ctl , qc = (activePhase & LMASK ) | ((pc - RC_UNIT ) & UMASK );
1999
- w .stackPred = (int )pc ; // set ctl stack link
1998
+ int sp = w .stackPred = (int )pc ; // set ctl stack link
2000
1999
w .phase = p ;
2001
2000
if (!compareAndSetCtl (pc , qc )) // try to enqueue
2002
2001
return w .phase = phase ; // back out on possible signal
@@ -2006,18 +2005,18 @@ private int deactivate(WorkQueue w, int phase) {
2006
2005
(qs = queues ) == null || (n = qs .length ) <= 0 )
2007
2006
return IDLE ; // terminating
2008
2007
int prechecks = Math .min (ac , 2 ); // reactivation threshold
2009
- for (int k = Math .max (n + ( n << 1 ) , SPIN_WAITS << 1 );;) {
2010
- WorkQueue q ; int cap ; ForkJoinTask <?>[] a ;
2008
+ for (int k = Math .max (n << 2 , SPIN_WAITS << 1 );;) {
2009
+ WorkQueue q ; int cap ; ForkJoinTask <?>[] a ; long c ;
2011
2010
if (w .phase == activePhase )
2012
2011
return activePhase ;
2013
2012
if (--k < 0 )
2014
2013
return awaitWork (w , p ); // block, drop, or exit
2015
- if ((k & 1 ) != 0 )
2016
- Thread .onSpinWait (); // interleave spins and rechecks
2017
- else if ((q = qs [k & (n - 1 )]) != null &&
2018
- (a = q .array ) != null && (cap = a .length ) > 0 &&
2014
+ if ((q = qs [k & (n - 1 )]) == null )
2015
+ Thread .onSpinWait ();
2016
+ else if ((a = q .array ) != null && (cap = a .length ) > 0 &&
2019
2017
a [q .base & (cap - 1 )] != null && --prechecks < 0 &&
2020
- ctl == qc && compareAndSetCtl (qc , pc ))
2018
+ (int )(c = ctl ) == activePhase &&
2019
+ compareAndSetCtl (c , (sp & LMASK ) | ((c + RC_UNIT ) & UMASK )))
2021
2020
return w .phase = activePhase ; // reactivate
2022
2021
}
2023
2022
}
0 commit comments