if (VM_Processor.getCurrentProcessor().needsSync) { VM_Processor.getCurrentProcessor().needsSync = false;  VM_Magic.isync(); synchronized(VM_Scheduler.syncObj) { VM_Scheduler.toSyncProcessors--; } }
  public static void threadSwitch(int whereFrom) throws VM_PragmaNoInline {    if (VM.BuildForThreadSwitchUsingControlRegisterBit) VM_Magic.clearThreadSwitchBit();    VM_Processor.getCurrentProcessor().threadSwitchRequested = 0;    if (!VM_Processor.getCurrentProcessor().threadSwitchingEnabled()) {       // thread in critical section: can't switch right now, defer 'till later      VM_Processor.getCurrentProcessor().threadSwitchPending = true;      return;    }    if (VM_Scheduler.debugRequested && VM_Scheduler.allProcessorsInitialized) {       // service "debug request" generated by external signal      VM_Scheduler.debuggerMutex.lock();      if (VM_Scheduler.debuggerQueue.isEmpty())      { // debugger already running        VM_Scheduler.debuggerMutex.unlock();      }      else      { // awaken debugger        VM_Thread t = VM_Scheduler.debuggerQueue.dequeue();        VM_Scheduler.debuggerMutex.unlock();        t.schedule();      }    }    if (!VM_Scheduler.attachThreadRequested.isZero()) {      // service AttachCurrentThread request from an external pthread      VM_Scheduler.attachThreadMutex.lock();      if (VM_Scheduler.attachThreadQueue.isEmpty())      { // JNIServiceThread already running        VM_Scheduler.attachThreadMutex.unlock();      }      else      { // awaken JNIServiceThread        VM_Thread t = VM_Scheduler.attachThreadQueue.dequeue();        VM_Scheduler.attachThreadMutex.unlock();        t.schedule();      }    }    if (VM_Scheduler.wakeupQueue.isReady()) {      VM_Scheduler.wakeupMutex.lock();      VM_Thread t = VM_Scheduler.wakeupQueue.dequeue();      VM_Scheduler.wakeupMutex.unlock();      if (t != null)      {        // VM_Scheduler.trace("VM_Thread",         // "threadSwitch: awaken ", t.getIndex());        t.schedule();      }    }    // Reset thread switch count for deterministic thread switching    if(VM.BuildForDeterministicThreadSwitching)       VM_Processor.getCurrentProcessor().deterministicThreadSwitchCount =         VM.deterministicThreadSwitchInterval;    //-#if RVM_WITH_ADAPTIVE_SYSTEM    // We use threadswitches as a rough approximation of time.     // Every threadswitch is a clock tick.    VM_Controller.controllerClock++;    //    // "The idle thread is boring, and does not deserve to be sampled"    //                           -- AOS Commandment Number 1    if (!VM_Thread.getCurrentThread().isIdleThread) {      // First, get the cmid for the method in which the yieldpoint was taken.      // Get pointer to my caller's frame      VM_Address fp = VM_Magic.getCallerFramePointer(VM_Magic.getFramePointer());       // Skip over wrapper to "real" method      fp = VM_Magic.getCallerFramePointer(fp);                                   int ypTakenInCMID = VM_Magic.getCompiledMethodID(fp);      // Next, get the cmid for that method's caller.      fp = VM_Magic.getCallerFramePointer(fp);      int ypTakenInCallerCMID = VM_Magic.getCompiledMethodID(fp);      // Determine if ypTakenInCallerCMID actually corresponds to a real       // Java stackframe.      boolean ypTakenInCallerCMIDValid = true;      VM_CompiledMethod ypTakenInCM =         VM_CompiledMethods.getCompiledMethod(ypTakenInCMID);      // Check for one of the following:      //    Caller is top-of-stack psuedo-frame      //    Caller is out-of-line assembly (no VM_Method object)      //    Caller is a native method      if (ypTakenInCallerCMID == STACKFRAME_SENTINAL_FP ||          ypTakenInCallerCMID == INVISIBLE_METHOD_ID    ||          ypTakenInCM.getMethod().getDeclaringClass().isBridgeFromNative()) {         ypTakenInCallerCMIDValid = false;      }       // Now that we have the basic information we need,       // notify all currently registered listeners      if (VM_RuntimeMeasurements.hasMethodListener()){        // set the Caller CMID to -1 if invalid        if (!ypTakenInCallerCMIDValid) ypTakenInCallerCMID = -1;          VM_RuntimeMeasurements.activateMethodListeners(ypTakenInCMID,                                                       ypTakenInCallerCMID,                                                        whereFrom);      }      if (ypTakenInCallerCMIDValid &&           VM_RuntimeMeasurements.hasContextListener()) {        // Have to start over again in case an intervening GC has moved fp         //    since the last time we did this.        // Get pointer to my caller's frame        fp = VM_Magic.getCallerFramePointer(VM_Magic.getFramePointer());        // Skip over wrapper to "real" method        fp = VM_Magic.getCallerFramePointer(fp);                                 VM_RuntimeMeasurements.activateContextListeners(fp, whereFrom);      }      if (VM_RuntimeMeasurements.hasNullListener()){        VM_RuntimeMeasurements.activateNullListeners(whereFrom);      }    }    //-#endif    // VM_Scheduler.trace("VM_Thread", "threadSwitch");    timerTickYield();  }