3232 * @author peter.lawrey
3333 */
3434public class AffinityLock {
35+ private static final Logger LOGGER = Logger .getLogger (AffinityLock .class .getName ());
36+
3537 // TODO It seems like on virtualized platforms .availableProcessors() value can change at
3638 // TODO runtime. We should think about how to adopt to such change
3739
@@ -42,8 +44,6 @@ public class AffinityLock {
4244 public static final long BASE_AFFINITY = AffinitySupport .getAffinity ();
4345 public static final long RESERVED_AFFINITY = getReservedAffinity0 ();
4446
45- private static final Logger LOGGER = Logger .getLogger (AffinityLock .class .getName ());
46-
4747 private static AffinityLock [] LOCKS ;
4848 private static NavigableMap <Integer , AffinityLock []> CORES ; // set by cpuLayout()
4949 private static final AffinityLock NONE = new AffinityLock (-1 , false , false );
@@ -73,12 +73,17 @@ public class AffinityLock {
7373 */
7474 public static void cpuLayout (CpuLayout cpuLayout ) {
7575 synchronized (AffinityLock .class ) {
76+ if (cpuLayout .equals (AffinityLock .cpuLayout ))
77+ return ;
7678 AffinityLock .cpuLayout = cpuLayout ;
7779 LOCKS = new AffinityLock [cpuLayout .cpus ()];
7880 int threads = cpuLayout .threadsPerCore ();
7981 CORES = new TreeMap <Integer , AffinityLock []>();
8082 for (int i = 0 ; i < cpuLayout .cpus (); i ++) {
81- AffinityLock al = LOCKS [i ] = new AffinityLock (i , ((BASE_AFFINITY >> i ) & 1 ) != 0 , ((RESERVED_AFFINITY >> i ) & 1 ) != 0 );
83+ boolean base1 = ((BASE_AFFINITY >> i ) & 1 ) != 0 ;
84+ boolean reservable1 = ((RESERVED_AFFINITY >> i ) & 1 ) != 0 ;
85+ LOGGER .log (Level .INFO , "cpu " + i + " base= " + base1 + " reservable= " + reservable1 );
86+ AffinityLock al = LOCKS [i ] = new AffinityLock (i , base1 , reservable1 );
8287 final int layoutId = al .cpuId ;
8388 int logicalCpuId = coreForId (layoutId );
8489 AffinityLock [] als = CORES .get (logicalCpuId );
@@ -111,8 +116,14 @@ public static CpuLayout cpuLayout() {
111116
112117 private static long getReservedAffinity0 () {
113118 String reservedAffinity = System .getProperty (AFFINITY_RESERVED );
114- if (reservedAffinity == null || reservedAffinity .trim ().isEmpty ())
115- return ((1 << PROCESSORS ) - 1 ) ^ BASE_AFFINITY ;
119+ if (reservedAffinity == null || reservedAffinity .trim ().isEmpty ()) {
120+ long reserverable = ((1 << PROCESSORS ) - 1 ) ^ BASE_AFFINITY ;
121+ if (reserverable == 0 && PROCESSORS > 1 ) {
122+ LOGGER .log (Level .INFO , "No isolated CPUs found, so assuming CPUs 1 to " + (PROCESSORS - 1 ) + " available." );
123+ return ((1 << PROCESSORS ) - 2 );
124+ }
125+ return reserverable ;
126+ }
116127 return Long .parseLong (reservedAffinity , 16 );
117128 }
118129
@@ -128,7 +139,7 @@ public static AffinityLock acquireLock() {
128139 /**
129140 * Assign any free core to this thread.
130141 * <p/>
131- * In reality, only one cpu is assigned, the rest of the threads for that core are reserved so they are not used.
142+ * In reality, only one cpu is assigned, the rest of the threads for that core are reservable so they are not used.
132143 *
133144 * @return A handle for the current AffinityLock.
134145 */
@@ -214,7 +225,7 @@ static String dumpLocks0(AffinityLock[] locks) {
214225 sb .append (i ).append (": " );
215226 if (al .assignedThread != null )
216227 sb .append (al .assignedThread ).append (" alive=" ).append (al .assignedThread .isAlive ());
217- else if (al .reserved )
228+ else if (al .reservable )
218229 sb .append ("Reserved for this application" );
219230 else if (al .base )
220231 sb .append ("General use CPU" );
@@ -228,14 +239,14 @@ else if (al.base)
228239 //// Non static fields and methods.
229240 private final int cpuId ;
230241 private final boolean base ;
231- private final boolean reserved ;
242+ private final boolean reservable ;
232243 boolean bound = false ;
233244 Thread assignedThread ;
234245
235- AffinityLock (int cpuId , boolean base , boolean reserved ) {
246+ AffinityLock (int cpuId , boolean base , boolean reservable ) {
236247 this .cpuId = cpuId ;
237248 this .base = base ;
238- this .reserved = reserved ;
249+ this .reservable = reservable ;
239250 }
240251
241252 /**
@@ -251,14 +262,14 @@ private void assignCurrentThread(boolean bind, boolean wholeCore) {
251262 }
252263
253264 /**
254- * Bind the current thread to this reserved lock.
265+ * Bind the current thread to this reservable lock.
255266 */
256267 public void bind () {
257268 bind (false );
258269 }
259270
260271 /**
261- * Bind the current thread to this reserved lock.
272+ * Bind the current thread to this reservable lock.
262273 *
263274 * @param wholeCore if true, also reserve the whole core.
264275 */
@@ -297,7 +308,7 @@ public void bind(boolean wholeCore) {
297308 }
298309
299310 private boolean canReserve () {
300- if (reserved ) return false ;
311+ if (! reservable ) return false ;
301312 if (assignedThread != null ) {
302313 if (assignedThread .isAlive ()) return false ;
303314 LOGGER .severe ("Lock assigned to " + assignedThread + " but this thread is dead." );
@@ -343,7 +354,7 @@ public void release() {
343354
344355 @ Override
345356 protected void finalize () throws Throwable {
346- if (reserved ) {
357+ if (reservable ) {
347358 LOGGER .warning ("Affinity lock for " + assignedThread + " was discarded rather than release()d in a controlled manner." );
348359 release ();
349360 }
0 commit comments