/** * Bind the current thread to this reservable lock. * * @param wholeCore if true, also reserve the whole core. */ public void bind(boolean wholeCore) { if (bound && assignedThread != null && assignedThread.isAlive()) throw new IllegalStateException("cpu " + cpuId + " already bound to " + assignedThread); if (wholeCore) { int core = coreForId(cpuId); for (AffinityLock al : CORES.get(core)) { if (bound && al.assignedThread != null && al.assignedThread.isAlive()) { LOGGER.severe("cpu " + al.cpuId + " already bound to " + al.assignedThread); } else { al.bound = true; al.assignedThread = Thread.currentThread(); } } if (LOGGER.isLoggable(Level.INFO)) { StringBuilder sb = new StringBuilder().append("Assigning core ").append(core); String sep = ": cpus "; for (AffinityLock al : CORES.get(core)) { sb.append(sep).append(al.cpuId); sep = ", "; } sb.append(" to ").append(assignedThread); LOGGER.info(sb.toString()); } } else if (cpuId >= 0) { bound = true; assignedThread = Thread.currentThread(); if (LOGGER.isLoggable(Level.INFO)) LOGGER.info("Assigning cpu " + cpuId + " to " + assignedThread); } if (cpuId >= 0) AffinitySupport.setAffinity(1L << cpuId); }
private static AffinityLock acquireCore(boolean bind, int cpuId, AffinityStrategy... strategies) { synchronized (AffinityLock.class) { for (AffinityStrategy strategy : strategies) { LOOP: for (AffinityLock[] als : CORES.descendingMap().values()) { for (AffinityLock al : als) if (!al.canReserve() || !strategy.matches(cpuId, al.cpuId)) continue LOOP; final AffinityLock al = als[0]; al.assignCurrentThread(bind, true); return al; } } } if (LOGGER.isLoggable(Level.WARNING)) LOGGER.warning("No reservable Core for " + Thread.currentThread()); return acquireLock(bind, cpuId, strategies); }
private static AffinityLock acquireLock(boolean bind, int cpuId, AffinityStrategy... strategies) { synchronized (AffinityLock.class) { for (AffinityStrategy strategy : strategies) { // consider all processors except cpu 0 which is usually used by the OS. // if you have only one core, this library is not appropriate in any case. for (int i = LOCKS.length - 1; i > 0; i--) { AffinityLock al = LOCKS[i]; if (al.canReserve() && (cpuId < 0 || strategy.matches(cpuId, al.cpuId))) { al.assignCurrentThread(bind, false); return al; } } } } if (LOGGER.isLoggable(Level.WARNING)) LOGGER.warning("No reservable CPU for " + Thread.currentThread()); return AffinityLock.NONE; }
/** Release the current AffinityLock which can be discarded. */ public void release() { Thread t = Thread.currentThread(); synchronized (AffinityLock.class) { for (AffinityLock al : LOCKS) { Thread at = al.assignedThread; if (at == t) { if (LOGGER.isLoggable(Level.INFO)) LOGGER.info("Releasing cpu " + al.cpuId + " from " + t); al.assignedThread = null; al.bound = false; } else if (at != null && !at.isAlive()) { LOGGER.warning("Releasing cpu " + al.cpuId + " from " + t + " as it is not alive."); al.assignedThread = null; al.bound = false; } } } AffinitySupport.setAffinity(BASE_AFFINITY); }