VM.assert(entryCounts[myProcessorId]==0);
VM._assert(entryCounts[myProcessorId]==0);
  void  startupRendezvous () throws VM_PragmaUninterruptible {    int myProcessorId = VM_Processor.getCurrentProcessorId();    int myNumber = VM_Magic.threadAsCollectorThread(VM_Thread.getCurrentThread()).getGCOrdinal();    int numExcluded = 0;  // number of RVM VPs NOT participating    rendezvousCount[myProcessorId] = 0;      if (VM.VerifyAssertions) {      if (entryCounts[myProcessorId]!=0) {	VM_Scheduler.trace("startupRendezvous:", "on entry entryCount =",entryCounts[myProcessorId]);	VM.assert(entryCounts[myProcessorId]==0);      }    }    if ( myNumber > 1 ) {      // enter barrier      //      entryCounts[myProcessorId] = 1;      VM_Magic.sync(); // update main memory so other processors will see it in "while" loop, below      // wait for "normal" other processors to show up, or be made non-participating      // ie. for their counts to go to 1 or -1 respectfully      //      for (int i = 1; i <= VM_Scheduler.numProcessors; ++i) {	while (entryCounts[i] == 0)	  waitABit(1);      }      // now also wait for native daemon processor to be excluded (done so by      // ordinal=1 thread in code below) or to arrive.      while (entryCounts[VM_Scheduler.nativeDPndx] == 0)	waitABit(1);      VM_Magic.isync();   // so subsequent instructions won't see stale values      if (trace_startup) VM_Scheduler.trace("startupRendezvous:", "leaving - my count =",				    entryCounts[myProcessorId]);      return;             // leave barrier    }    // Thread with gcOrdinal==1 must detect processors whose active threads are    // stuck in Native C, block them there, and make them non-participants    //    for (int i = 1; i <= VM_Scheduler.numProcessors; ++i) {      if ( i == myProcessorId ) continue;  // my count not yet set      while (entryCounts[i] == 0) {	waitABit(1);     // give missing thread a chance to show up	// if missing thread/processor is in native, block it there,	// and set count to -1 to indicate a non-participant for this GC	//	if ( VM_Scheduler.processors[i].lockInCIfInC() ) {	  numExcluded++;	  if (trace_unusual) VM_Scheduler.trace("startupRendezvous:","TAKING OUT processor",i);	  removeProcessor( i );	}      }      if (trace_startup) {	if (entryCounts[i] == 1)	  VM_Scheduler.trace("startupRendezvous:","processor INCLUDED - id =",i);	else	  VM_Scheduler.trace("startupRendezvous:","processor EXCLUDED - id =",i);      }    }    if (trace_startup) VM_Scheduler.trace("startupRendezvous","numExcluded =",numExcluded);    if ( !VM.BuildForSingleVirtualProcessor && VM_Scheduler.processors[VM_Scheduler.nativeDPndx]!=null) {      // If it is the NativeProcessor (its collector thread) that is executing here      // just fall thru to end, to set our entryCount, sync & return. Else, decide      // what to do with the NativeProcessor      if ( myProcessorId == VM_Scheduler.nativeDPndx ) {	if (trace_startup) VM_Scheduler.trace("startupRendezvous:","NativeProcessor has ordinal 1, will participate");      }      else {	if (trace_startup) VM_Scheduler.trace("startupRendezvous:","checking NativeDaemonProcessor");	int loopCount = 1;	VM_Processor ndvp = VM_Scheduler.processors[VM_Scheduler.nativeDPndx];	while (entryCounts[VM_Scheduler.nativeDPndx] == 0) {	  if ( VM_Scheduler.processors[VM_Scheduler.nativeDPndx].blockInWaitIfInWait() ) {	    numExcluded++;	    if (trace_startup)	      VM_Scheduler.trace("startupRendezvous:","TAKING OUT NATIVE DAEMON PROCESSOR");	    removeProcessor( VM_Scheduler.nativeDPndx );	  }	  waitABit(1);     // give missing thread a chance to show up	  if (trace_startup) {	    loopCount++;	    if (loopCount%100 == 0)	      VM_Scheduler.trace("startupRendezvous:","in native processor loop - loopCount =",loopCount);	  }	}	// native processor is now either Participating or blocked in sigwait		if (trace_unusual || trace_startup) {	  if ( entryCounts[VM_Scheduler.nativeDPndx] == 1 )	    VM_Scheduler.trace("startupRendezvous:","NativeDaemonProcessor IN");	  else 	    VM_Scheduler.trace("startupRendezvous:","NativeDaemonProcessor OUT");	  VM_Scheduler.trace("startupRendezvous:","native processor status =",			     VM_Processor.vpStatus[ndvp.vpStatusIndex]);	}      }      // include NativeDaemonProcessor in set of processors to rendezvous      maxProcessorId = VM_Scheduler.numProcessors + 1;    }  // !VM.BuildForSingleVirtualProcessor    else {      // compiled ForSingleProcessor: there is no nativeDaemonProcessor       if (trace_startup) VM_Scheduler.trace("startupRendezvous:", "forcing native daemon count to -1");      entryCounts[VM_Scheduler.nativeDPndx] = -1;       maxProcessorId = VM_Scheduler.numProcessors;    }    // after deciding whos in and whos out, ordinal 1 thread enters barrier by    // setting its count to 1 (maybe this can be done earlier so others can    // get through the count loop quicker)    //    entryCounts[myProcessorId] = 1;    VM_Magic.sync();   // update main memory so other processors will see it in "while" loop    VM_Magic.isync();  // so subsequent instructions won't see stale values    if (trace_startup) VM_Scheduler.trace("startupRendezvous:", "leaving - my count =",				  entryCounts[myProcessorId]);    return;            // leave barrier  }  // startupRendezvous  /**   * reset the rendezvous counters for all VPs to 0.   * Also sets numRealProcessors to number of real CPUs.   */  void resetRendezvous () throws VM_PragmaUninterruptible {    for ( int i = 1; i <= VM_Scheduler.numProcessors; i++)      entryCounts[i] = 0;    entryCounts[VM_Scheduler.nativeDPndx] = 0;    if ( ! VM.BuildForSingleVirtualProcessor) {      // Set number of Real processors on the running computer. This will allow      // waitABit() to spin when running with fewer VM_Procssors than real processors      numRealProcessors = VM.sysCall0(VM_BootRecord.the_boot_record.sysNumProcessorsIP);    }    VM_Magic.sync();      // make other threads/processors see the update  }