VM_Address getBufferAndWait () {
VM_Address getBufferAndWait () throws VM_PragmaLogicallyUninterruptible {
  VM_Address getBufferAndWait () {    VM_Address  temp;    int debug_counter = 0;    int debug_counter_counter = 0;    if(trace) VM.sysWrite(" GCWorkQueue.getBufferAndWait entered\n");    synchronized(this) {      // see if any work to do, if so, return next work buffer      if (!bufferHead.isZero()) {	temp = bufferHead;	bufferHead = VM_Address.fromInt(VM_Magic.getMemoryWord(temp));	return temp;       }      if (numThreads == 1) return VM_Address.zero();  // only 1 thread, no work, just return      numThreadsWaiting++;   // add self to number of gc threads waiting            // if this is last gc thread, ie all threads waiting, then we are done      //      if (numThreadsWaiting == numThreads) {	numThreadsWaiting--;         // take ourself out of count	completionFlag = true;       // to lets waiting threads return	return VM_Address.zero();      }    } // end of synchronized block        // wait for work to arrive (or for end) currently spin a while & then     // recheck the work queue (lacking a "system" level wait-notify)    //    while (true) {            // if we had a system wait-notify...we could do following...      // try { wait(); }       // catch (InterruptedException e) {      //	    VM.sysWrite("Interrupted Exception in getBufferAndWait")      //		}      if (debug) {	if ( (++debug_counter % 100000) == 0) {	  VM_Scheduler.trace("VM_GCWorkQueue","waiting - numThreadsWaiting =",numThreadsWaiting);	  if ( ++debug_counter_counter > 10)	    VM.shutdown(-2);	}      }            //spin here a while      int x = spinABit(5);            synchronized(this) {	// see if any work to do	if (!bufferHead.isZero()) {	  temp = bufferHead;	  bufferHead = VM_Magic.getMemoryAddress(temp);	  numThreadsWaiting--;	  return temp; 	}	//currently no work - are we finished	if ( completionFlag == true) {	  numThreadsWaiting--;         // take ourself out of count	  if (numThreadsWaiting == 0)	    completionFlag = false;    // last thread out resets completion flag	  return VM_Address.zero(); // are we complete	}      } // end of synchronized block          } // end of while loop      } // end of method