void MemRequest::setStateAckDone(TimeDelta_t lat) { MemRequest *orig = setStateAckOrig; if(orig==0) return; if (orig->mt == mt_setState) orig->needsDisp |= needsDisp; setStateAckOrig = 0; I(orig->pendingSetStateAck>0); orig->pendingSetStateAck--; if (orig->pendingSetStateAck<=0) { if(orig->mt == mt_req) { orig->redoReqCB.schedule(lat); }else if (orig->mt == mt_reqAck) { orig->redoReqAckCB.schedule(lat); }else if (orig->mt == mt_setState) { //I(orig->setStateAckOrig==0); //orig->ack(); orig->convert2SetStateAck(orig->ma, orig->needsDisp); I(orig->currMemObj == orig->creatorObj); //orig->startSetStateAck(); // NOTE: no PortManager because this message is already accounted orig->redoSetStateAckAbs(globalClock); //orig->setStateAckDone(); No recursive/dep chains for the moment }else{ I(0); } } }
void MemRequest::setStateAckDone(TimeDelta_t lat) { MemRequest *orig = setStateAckOrig; if(orig==0) return; setStateAckOrig = 0; I(orig->pendingSetStateAck>0); orig->pendingSetStateAck--; if (orig->pendingSetStateAck<=0) { if(orig->mt == mt_req) { orig->redoReqCB.schedule(lat); }else if (orig->mt == mt_reqAck) { orig->redoReqAckCB.schedule(lat); }else if (orig->mt == mt_setState) { //I(orig->setStateAckOrig==0); //orig->ack(); orig->convert2SetStateAck(orig->ma); I(orig->currMemObj == orig->creatorObj); orig->startSetStateAck(); //orig->setStateAckDone(); No recursive/dep chains for the moment }else{ I(0); } } }
int32_t MRouter::sendSetStateAll(MemRequest *mreq, MsgAction ma, TimeDelta_t lat) /* send setState to others, return how many {{{1 */ { if(up_node.empty()) return 0; // top node? bool doStats = mreq->getStatsFlag(); AddrType addr = mreq->getAddr(); if (addr == 0xa000000005601213) { I(0); } I(mreq->isSetState()); int32_t conta = 0; for(size_t i=0;i<up_node.size();i++) { MemRequest *breq = MemRequest::createSetState(self_mobj, mreq->getCreator(), ma, addr, doStats); breq->addPendingSetStateAck(mreq); breq->startSetState(up_node[i], lat); conta++; } return conta; }
void meminterface_start_snoop_req(uint64_t addr, bool inv, uint16_t coreid, void *_mreq) { MemRequest *mreq = (MemRequest *)_mreq; //MSG("@%lld snoop %s 0x%lx %d %s",globalClock, mreq->getCurrMem()->getName(), addr, mreq->getAction(), inv?"inv":"wb"); mreq->convert2SetStateAck(); mreq->getCurrMem()->doSetStateAck(mreq); }
int32_t MRouter::sendSetStateOthers(MemRequest *mreq, MsgAction ma, TimeDelta_t lat) /* send setState to others, return how many {{{1 */ { if (up_node.size() <= 1) return 0; // if single node, for sure it does not get one bool doStats = mreq->getStatsFlag(); AddrType addr = mreq->getAddr(); MemObj *skip_mobj = 0; UPMapType::const_iterator it = up_map.find(mreq->getHomeNode()); I(it != up_map.end()); skip_mobj = it->second; int32_t conta = 0; I(mreq->isReq() || mreq->isReqAck()); for(size_t i=0;i<up_node.size();i++) { if (up_node[i] == skip_mobj) continue; if (addr == 0xa000000005601213) { I(0); } MemRequest *breq = MemRequest::createSetState(self_mobj, mreq->getCreator(), ma, addr, doStats); breq->addPendingSetStateAck(mreq); breq->startSetState(up_node[i], lat); conta++; } return conta; }
void MemRequest::dump_all() { MemRequest *mreq = actPool.firstInUse(); while(mreq) { mreq->dump_calledge(0,true); mreq = actPool.nextInUse(mreq); } }
void MemSourceObject::initialize(){ //MemSourceState *myState = dynamic_cast<MemSourceState *>( getState() ); IntVTime sendTime = dynamic_cast<const IntVTime&>(getSimulationTime()); MemRequest *firstEvent = new MemRequest(sendTime, sendTime + 1, this, this); firstEvent->setProcessor(getName()); firstEvent->setStartTime(0); this->receiveEvent(firstEvent); }
int32_t MRouter::sendSetStateOthersPos(uint32_t pos, MemRequest *mreq, MsgAction ma, TimeDelta_t lat) /* send setState to specific pos, return how many {{{1 */ { if (up_node.size() <= 1) return 0; // if single node, for sure it does not get one bool doStats = mreq->getStatsFlag(); AddrType addr = mreq->getAddr(); if (addr == 0xa000000005601213) { I(0); } MemRequest *breq = MemRequest::createSetState(self_mobj, mreq->getCreator(), ma, addr, doStats); breq->addPendingSetStateAck(mreq); breq->startSetState(up_node[pos], lat); return 1; }
void MemSourceObject::executeProcess(){ MemSourceState *myState = static_cast<MemSourceState *>(getState()); MemRequest* received = NULL; IntVTime sendTime = static_cast<const IntVTime&>(getSimulationTime()); //int id = getObjectID()->getSimulationObjectID(); while(true == haveMoreEvents()) { received = (MemRequest*)getEvent(); if(received != NULL){ myState->filter.update((double)((IntVTime &)getSimulationTime() - received->getStartTime() ).getTime() ); int requestsCompleted = myState->numMemRequests; if (requestsCompleted < maxMemRequests ) { double ldelay = 1.0; // we want the memRequest to get there at the exact scheduled time SimulationObject *receiver = getObjectHandle(destObjName); IntVTime recvTime = sendTime + (int) ldelay; MemRequest *newMemRequest = new MemRequest(sendTime, recvTime, this, receiver); newMemRequest->setProcessor(getName()); newMemRequest->setStartTime(sendTime.getTime()); myState->numMemRequests++; myState->oldDelay = sendTime; receiver->receiveEvent(newMemRequest); } } } }
void StdMemoryOS::attemptToEmptyQueue(ulong vaddr, ulong phPage) { // attempt a bypass long vPage = GMemorySystem::calcPage(vaddr); std::vector<MemRequest *>::iterator it = pendingReqs.begin(); if(it != pendingReqs.end()) { MemRequest *mm = *it; long tmpPage = GMemorySystem::calcPage(mm->getVaddr()); if(vPage == tmpPage) { launchReq(mm, GMemorySystem::calcPAddr(GMemorySystem::calcFullPage(vPage), mm->getVaddr())); it = pendingReqs.erase(it); } else it++ ; } // wakeup the next request if(!pendingReqs.empty()) { MemRequest *thisReq = pendingReqs.front(); pendingReqs.erase(pendingReqs.begin()); serviceRequest(thisReq); } }
void PriorityBus::processQ() { // if this was called, there *must* be a req waiting I(!allQueuesEmpty()); int32_t selectedQ = -1; for(int32_t q = 0; q < LastQ; q++) { if(!reqQs[q].empty()) { selectedQ = q; break; } } I(selectedQ != -1); MemRequest *mreq = reqQs[selectedQ].front(); reqQs[selectedQ].pop_front(); Time_t reqArrivalTime = timeQs[selectedQ].front(); timeQs[selectedQ].pop_front(); //determining when to dispatch the request bool goUp = ((selectedQ == upHighP) || (selectedQ == upLowP)); Time_t when = 0; if(goUp) { if (mreq->getMemOperation() == MemPush || mreq->getMemOperation() == MemWrite) { when = busPort->nextSlot(controlOcc); }else{ when = busPort->nextSlot(dataOcc)+delay; } } else { // req is going down if (mreq->getMemOperation() == MemPush || mreq->getMemOperation() == MemWrite) { when = busPort->nextSlot(dataOcc)+delay; }else{ when = busPort->nextSlot(controlOcc); } } tHist[selectedQ]->sample(reqQs[selectedQ].size()); avgTime[selectedQ]->sample(when - reqArrivalTime); //counting the different types of bypass if(selectedQ == upHighP && !timeQs[upLowP].empty()) { if(reqArrivalTime > timeQs[upLowP].front()) nBypassUp.inc(); } if(selectedQ == downHighP && !timeQs[downLowP].empty()) { if(reqArrivalTime > timeQs[downLowP].front()) nBypassDown.inc(); } if(selectedQ == upHighP && !timeQs[downLowP].empty()) { // a req with high prio going up bypassed a low prio req going down if(reqArrivalTime > timeQs[downLowP].front()) nBypassDirection.inc(); } // scheduling next callback *has* to be before sending reqs up or down. if(!allQueuesEmpty()) processQCB.scheduleAbs(busPort->calcNextSlot()); // dispatching the request if(goUp) mreq->goUpAbs(when); else mreq->goDownAbs(when, lowerLevel[0]); }