/**
   * 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);
 }