int loopcheck = 0;
  private VM_Thread getRunnableThread() throws InlinePragma {    int loopcheck = 0;    for (int i=transferQueue.length(); 0<i; i--) {      transferMutex.lock();      VM_Thread t = transferQueue.dequeue();      transferMutex.unlock();      if (t.isGCThread){        if (VM.TraceThreadScheduling > 1) VM_Scheduler.trace("VM_Processor", "getRunnableThread: collector thread", t.getIndex());        return t;      } else if (t.beingDispatched && t != VM_Thread.getCurrentThread()) { // thread's stack in use by some OTHER dispatcher        if (VM.TraceThreadScheduling > 1) VM_Scheduler.trace("VM_Processor", "getRunnableThread: stack in use", t.getIndex());        transferMutex.lock();        transferQueue.enqueue(t);        transferMutex.unlock();      } else {        if (VM.TraceThreadScheduling > 1) VM_Scheduler.trace("VM_Processor", "getRunnableThread: transfer to readyQueue", t.getIndex());        readyQueue.enqueue(t);      }    }    if ((reportedTimerTicks % VM_Scheduler.numProcessors) + 1 == id) {      // it's my turn to check the io queue early to avoid starvation      // of threads in io wait.      // We round robin this among the virtual processors to avoid serializing      // thread switching in the call to select.      if (ioQueue.isReady()) {        VM_Thread t = ioQueue.dequeue();        if (VM.TraceThreadScheduling > 1) VM_Scheduler.trace("VM_Processor", "getRunnableThread: ioQueue (early)", t.getIndex());        if (VM.VerifyAssertions) VM._assert(t.beingDispatched == false || t == VM_Thread.getCurrentThread()); // local queue: no other dispatcher should be running on thread's stack        return t;      }    }    // FIXME - Need to think about whether we want a more    // intelligent way to do this; for example, handling SIGCHLD,    // and using that to implement the wakeup.  Polling is considerably    // simpler, however.    if ((reportedTimerTicks % NUM_TICKS_BETWEEN_WAIT_POLL) == id) {      VM_Thread result = null;      processWaitQueueLock.lock();      if (processWaitQueue.isReady()) {        VM_Thread t = processWaitQueue.dequeue();        if (VM.VerifyAssertions) VM._assert(t.beingDispatched == false || t == VM_Thread.getCurrentThread()); // local queue: no other dispatcher should be running on thread's stack        result = t;      }      processWaitQueueLock.unlock();      if (result != null)        return result;    }    if (!readyQueue.isEmpty()) {      VM_Thread t = readyQueue.dequeue();      if (VM.TraceThreadScheduling > 1) VM_Scheduler.trace("VM_Processor", "getRunnableThread: readyQueue", t.getIndex());      if (VM.VerifyAssertions) VM._assert(t.beingDispatched == false || t == VM_Thread.getCurrentThread()); // local queue: no other dispatcher should be running on thread's stack      return t;    }    if (ioQueue.isReady()) {      VM_Thread t = ioQueue.dequeue();      if (VM.TraceThreadScheduling > 1) VM_Scheduler.trace("VM_Processor", "getRunnableThread: ioQueue", t.getIndex());      if (VM.VerifyAssertions) VM._assert(t.beingDispatched == false || t == VM_Thread.getCurrentThread()); // local queue: no other dispatcher should be running on thread's stack      return t;    }    if (!idleQueue.isEmpty()) {      VM_Thread t = idleQueue.dequeue();      if (VM.TraceThreadScheduling > 1) VM_Scheduler.trace("VM_Processor", "getRunnableThread: idleQueue", t.getIndex());      if (VM.VerifyAssertions) VM._assert(t.beingDispatched == false || t == VM_Thread.getCurrentThread()); // local queue: no other dispatcher should be running on thread's stack      return t;    }    VM._assert(VM.NOT_REACHED); // should never get here (the idle thread should always be: running, on the idleQueue, or (maybe) on the transferQueue)    return null;  }