Пример #1
0
 TimeDelta_t SMPSystemBus::finalizePush(MemRequest *mreq)
{
  PAddr addr  = mreq->getPAddr();
  SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq);
  
  pendReqsTable.erase(mreq);
	  if (mreq->isDataReq())
	  {
	  	
	  	int nLesserEpochs=processResponses(mreq);
	 	//Version combining has concluded
    	//doVCRCB::scheduleAbs(busDelay*wrSize+nextSlot(mreq)+delay, this, mreq);
	 	if (VCRMaxCount.getValue()<VCRCount)
  			VCRMaxCount.inc();
  		if (sreq->needsData()|| sreq->getMemOperation()==MemPush)VCRCount--;
  		
		 l2DataProv.sample(nLesserEpochs);
		 mreq->getVcacheFlags()->clear();

 		 //Account for all bus transfers for version combination
	  	 return busDelay*nLesserEpochs;
	  	}
	  	else
			I(0);//Should not be called for any other reason
		return 0;
}
Пример #2
0
void SMPSystemBus::finalizeAccess(MemRequest *mreq)
{
  PAddr addr  = mreq->getPAddr();
  SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq);
  
  pendReqsTable.erase(mreq);
 
  // request completed, respond to requestor 
  // (may have to come back later to go to memory)
  sreq->goUpAbs(nextSlot(mreq)+delay);  
}
Пример #3
0
void SMPProtocol::sendWriteBack(PAddr addr, CallbackBase *cb)
{
    //cb->destroy();
    IJ(0);
#if 0
    IJ(cb==NULL);
    SMPMemRequest *sreq = SMPMemRequest::create(pCache, addr, MemPush, true, NULL, MeshMemWriteBack);
    sreq->addDstNode(pCache->getL2NodeID(addr));
    sreq->msgOwner = pCache;
    pCache->sendBelow(sreq);
#endif
}
Пример #4
0
void SMPSystemBus::doWrite(MemRequest *mreq)
{
  SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq);

  // no need to snoop, go straight to memory
  if(!sreq->needsSnoop()) {
    goToMem(mreq);
    return;
  }

  if(pendReqsTable.find(mreq) == pendReqsTable.end()) {

    unsigned numSnoops = getNumSnoopCaches(sreq);

    // operation is starting now, add it to the pending requests buffer
    pendReqsTable[mreq] = getNumSnoopCaches(sreq);

    if(!numSnoops) { 
      // nothing to snoop on this chip
      finalizeWrite(mreq);
      return;
      // TODO: even if there is only one processor on each chip, 
      // request is doing two rounds: snoop and memory
    }

	//VERSION COMBINING REGISTER ALLOCATED HERE
	#ifdef TLS
		if (mreq->isDataReq()&& sreq->needsData())VCRCount++;
	#endif
    // distribute requests to other caches, wait for responses
	 for(uint i = 0; i < upperLevel.size(); i++) {
      if(upperLevel[i] != static_cast<SMPMemRequest *>(mreq)->getRequestor()) {
	upperLevel[i]->returnAccess(mreq);
      }
    }
  } 
  else {
    // operation has already been sent to other caches, receive responses

    I(pendReqsTable[mreq] > 0);
    I(pendReqsTable[mreq] <= (int) upperLevel.size());

    pendReqsTable[mreq]--;
    if(pendReqsTable[mreq] != 0) {
      // this is an intermediate response, request is not serviced yet
      return;
    }

    // this is the final response, request can go up now
    finalizeWrite(mreq);
  }
}
Пример #5
0
void SMPSystemBus::doPush(MemRequest *mreq)
{
#ifdef TLS
   SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq);
   TimeDelta_t VCRDelay;
   PAddr addr= mreq->getPAddr();
  // no need to snoop, go straight to memory
  if(!sreq->needsSnoop()) {
    goToMem(mreq);
    return;
  }

  if(pendReqsTable.find(mreq) == pendReqsTable.end()) {

    unsigned numSnoops = getNumSnoopCaches(sreq);

    // operation is starting now, add it to the pending requests buffer
    pendReqsTable[mreq] = getNumSnoopCaches(sreq);

   	VCRCount++;
    // distribute requests to other caches, wait for responses
    for(uint i = 0; i < upperLevel.size(); i++) {
      if(upperLevel[i] != static_cast<SMPMemRequest *>(mreq)->getRequestor()) {
	upperLevel[i]->returnAccess(mreq);
      }
    }
  return;
  } 
  else {
    // operation has already been sent to other caches, receive responses

    I(pendReqsTable[mreq] > 0);
    I(pendReqsTable[mreq] <= (int) upperLevel.size());

    pendReqsTable[mreq]--;
    if(pendReqsTable[mreq] != 0) {
      // this is an intermediate response, request is not serviced yet
      return;
    }

    // this is the final response, Request will now be sent down
    VCRDelay=finalizePush(mreq);
    mreq->goDown(VCRDelay+delay, lowerLevel[0]);
  }
 #else 
  	mreq->goDown(delay, lowerLevel[0]);
 #endif
}
Пример #6
0
void SMPSystemBus::finalizeAccess(MemRequest *mreq)
{
  PAddr addr  = mreq->getPAddr();
  SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq);
  
  pendReqsTable.erase(mreq);
  #ifdef TLS
	  if (mreq->isDataReq())
	  {
	  	
	  	int nLesserEpochs=processResponses(mreq);
	 	//Version combining has concluded
    	//doVCRCB::scheduleAbs(busDelay*wrSize+nextSlot(mreq)+delay, this, mreq);
	 	if (VCRMaxCount.getValue()<VCRCount)
  			VCRMaxCount.inc();
  		if (sreq->needsData()|| sreq->getMemOperation()==MemPush)VCRCount--;
  		
		 l2DataProv.sample(nLesserEpochs);
		 mreq->getVcacheFlags()->clear();

 		
 		 //Account for all bus transfers for version combination
		 sreq->goUpAbs(busDelay*nLesserEpochs+nextSlot(mreq)+delay); 
	  	}
	  	else
	  	  	 sreq->goUpAbs(nextSlot(mreq)+delay);
	#else
	  sreq->goUpAbs(nextSlot(mreq)+delay);  
   #endif
 
  // request completed, respond to requestor 
  // (may have to come back later to go to memory)

}
Пример #7
0
void SMPCache::returnAccess(MemRequest *mreq)
{
  SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq);
  MemOperation memOp = sreq->getMemOperation();

  if(sreq->getRequestor() == this) {
    // request from this cache (response is ready)

    if(memOp == MemRead) {
      protocol->readMissAckHandler(sreq);
    } 
    else if(memOp == MemReadW) {
      if(sreq->needsData()) {
	protocol->writeMissAckHandler(sreq);
      } else {
	protocol->invalidateAckHandler(sreq);
      }
    } 
    else if(memOp == MemWrite) {
      I(!sreq->needsData());
      I(sreq->needsSnoop());
      protocol->invalidateAckHandler(sreq);
    }
    else if(memOp == MemPush) {
      protocol->writeBackAckHandler(sreq);
    }
  } else {
    receiveFromBelow(sreq);
  }
}
Пример #8
0
int SMPSystemBus::processResponses(MemRequest *mreq)
{
		SMPMemRequest *sreq = static_cast<SMPMemRequest *>(mreq);
		typedef std::vector<tls::CacheFlags>::iterator ItVcacheFlags;
		int nLesserEpochs=0;
		int wrSize=(sreq->getVcacheFlags())->size();
		//I(wrSize<=nProcs);

		//MEM ACCESS IN NO LONGER NECESSARY
		//Epoch checks are now done in the MESI protocol
		//So if line with proper epoch is not found the tag is set to 0
		//Consequently standard MESI causes request to go down to memory
		//Still has mem access code to prevent breaking further code
		if (sreq->getMemOperation()==MemReadW)
		{
			if (!wrSize)
			{
				//No other cache has line
				sreq->setClearOthersExposed();
				if (sreq->needsData())
					sreq->setMemAccess();
				return 0;
			}
			else
			{
				 sreq->clearSetOthersExposed(); 
				 sreq->clearClearOthersExposed()	;
				 ItVcacheFlags itVcacheFlags;
				 for (itVcacheFlags=sreq->getVcacheFlags()->begin();itVcacheFlags!=sreq->getVcacheFlags()->end();itVcacheFlags++)
				 {
				 	//If there are lines with epoch number greater than mine then set Others exposed
				 	if((*itVcacheFlags).getEpoch()->getClock()<(sreq->getOriginalRequest()->getEpoch())->getClock())
				 	{
				 		nLesserEpochs++;
				 	}
				 	else
				  		sreq->setSetOthersExposed();
				 }		  
				 if (!nLesserEpochs) 
				 {
				 	sreq->setMemAccess();
				 	sreq->setClearOthersExposed();
				 }
 				//If write miss then Lesser epochs makes sense
				 return sreq->needsData()? nLesserEpochs:0;

			}
		}
		if  (sreq->getMemOperation()==MemRead)
		{
			if (!wrSize)
			{
				//No other cache has line
				if (sreq->needsData())
					sreq->setMemAccess();
				return 0;
			}	
			else
			{
		    	 sreq->clearMemAccess();
				 sreq->clearSetOthersExposed(); 	
				 ItVcacheFlags itVcacheFlags;
				 for (itVcacheFlags=sreq->getVcacheFlags()->begin();itVcacheFlags!=sreq->getVcacheFlags()->end();itVcacheFlags++)
				 {
				 	//If there are lines with epoch number greater than mine then set exposed read
				 	if((*itVcacheFlags).getEpoch()->getClock()<(sreq->getOriginalRequest()->getEpoch())->getClock())
				 	{
				 		nLesserEpochs++;
				 	}
				 	else
				  		sreq->setSetOthersExposed();
				 }		  
				 if (!nLesserEpochs) sreq->setMemAccess();
				 return nLesserEpochs;
			}
		}
		if (sreq->getMemOperation()==MemPush)
		{
 			ItVcacheFlags itVcacheFlags;
			for (itVcacheFlags=sreq->getVcacheFlags()->begin();itVcacheFlags!=sreq->getVcacheFlags()->end();itVcacheFlags++)
				 {
					//Actual VCR
				 	if((*itVcacheFlags).getEpoch()->getClock()<(sreq->getOriginalRequest()->getEpoch())->getClock())
				 	{
				 		nLesserEpochs++;
				 	}
				 }		  
			return nLesserEpochs;
		}
		return 0;//All other cases
}