VM_Entrypoints.lockoutProcessorField.offset,
VM_Entrypoints.lockoutProcessorField.getOffset(),
  private void initiateCollection() throws VM_PragmaUninterruptible {    int maxCollectorThreads;    // check that scheduler initialization is complete    //	    if (!VM_Scheduler.allProcessorsInitialized) {      VM.sysWrite(" Garbage collection required before system fully initialized\n");      VM.sysWrite(" Specify larger than default heapsize on command line\n");      VM_Scheduler.dumpStack();      VM.shutdown(-1);    }    if (debug_native) {      //      VM_Scheduler.trace("VM_Handshake:initiateCollection","dumping machine...");      //      VM_Scheduler.dumpVirtualMachine();      VM_Scheduler.trace("\nVM_Handshake:initiateCollection","collectorQueue:");      VM_Scheduler.writeString("before waiting:"); VM_Scheduler.collectorQueue.dump();    }    // wait for all gc threads to finish preceeding collection cycle    // include NativeDaemonProcessor collector thread in the count - if it exists    // check for null to allow builds without a NativeDaemon (see VM_Scheduler)    if (!VM.BuildForSingleVirtualProcessor && VM_Scheduler.processors[VM_Scheduler.nativeDPndx] != null )      maxCollectorThreads = VM_Scheduler.numProcessors + 1;      else      maxCollectorThreads = VM_Scheduler.numProcessors;    VM_Scheduler.collectorMutex.lock();    while (VM_Scheduler.collectorQueue.length() < maxCollectorThreads) {      VM_Scheduler.collectorMutex.unlock();      if (trace) VM_Scheduler.trace("VM_Handshake", "mutator: waiting for previous collection to finish");      VM_Thread.getCurrentThread().yield();      VM_Scheduler.collectorMutex.lock();    }    VM_Scheduler.collectorMutex.unlock();    if (debug_native) {      VM_Scheduler.writeString("after waiting:"); VM_Scheduler.collectorQueue.dump();    }        // Acquire global lockout field (at fixed address in the boot record).    // This field will be released when gc completes    while (true) {      int lockoutVal = VM_Magic.prepare(VM_BootRecord.the_boot_record,					VM_Entrypoints.lockoutProcessorField.offset);      if ( lockoutVal == 0) {	if(VM_Magic.attempt(VM_BootRecord.the_boot_record,			    VM_Entrypoints.lockoutProcessorField.offset,			    0, LOCKOUT_GC_WORD))	  break;      }      else {	if (debug_native) VM_Scheduler.traceHex("VM_Handshake:initiateCollection",					     "lockoutLock contains",lockoutVal);      }    }        // reset counter for collector threads arriving to participate in the collection    VM_CollectorThread.participantCount[0] = 0;    // reset rendezvous counters to 0, the decision about which collector threads    // will participate has moved to the run method of CollectorThread    //    VM_CollectorThread.gcBarrier.resetRendezvous();    // scan all the native Virtual Processors and attempt to block those executing    // native C, to prevent returning to java during collection.  the first collector    // thread will wait for those not blocked to reach the SIGWAIT state.    // (see VM_CollectorThread.run)    //    for (int i = 1; i <= VM_Processor.numberNativeProcessors; i++) {      if (VM.VerifyAssertions) VM._assert(VM_Processor.nativeProcessors[i] != null);      VM_Processor.nativeProcessors[i].lockInCIfInC();      if (trace) {        int newStatus =  VM_Processor.vpStatus[VM_Processor.nativeProcessors[i].vpStatusIndex];        VM_Scheduler.trace("VM_Handshake.initiateCollection:", "Native Processor", i);        VM_Scheduler.trace("                                ", "new vpStatus    ", newStatus);      }    }    // Dequeue and schedule collector threads on ALL RVM Processors,    // including those running system daemon threads (ex. NativeDaemonProcessor)    //    VM_Scheduler.collectorMutex.lock();    while (VM_Scheduler.collectorQueue.length() > 0) {      VM_Thread t = VM_Scheduler.collectorQueue.dequeue();      t.scheduleHighPriority();      VM_Processor p = t.processorAffinity;      // set thread switch requested condition in VP      p.threadSwitchRequested = -1;    }    VM_Scheduler.collectorMutex.unlock();      }   // initiateCollection