bool SingleMSHR<Addr_t, Cache_t>::issue(Addr_t paddr, MemOperation mo) { MSHRit it = ms.find(calcLineAddr(paddr)); nUse.inc(); if(mo == MemRead) nUseReads.inc(); if(mo == MemWrite) nUseWrites.inc(); if(!overflow.empty()) { return false; } I(nFreeEntries >= 0 && nFreeEntries <=nEntries); if(it == ms.end()) { if(nFreeEntries > 0) { ms[calcLineAddr(paddr)].firstRequest(paddr, calcLineAddr(paddr), nReads, nWrites, mo); bf.insert(calcLineAddr(paddr)); nFreeEntries--; #ifdef MSHR_BASICOCCSTATS updateOccHistogram(); #endif nOutsReqs++; #ifdef MSHR_BASICOCCSTATS if(mo == MemRead) occStats->incRdReqs(); #endif nIssuesNewEntry.inc(); avgQueueSize.sample(0); checkSubEntries(paddr, mo); #ifdef MSHR_EXTRAOCCSTATS occStats->sampleEntry( calcLineAddr(paddr) ); #endif return true; } } return false; }
void SingleMSHR<Addr_t, Cache_t>::addEntry(Addr_t paddr, CallbackBase *c, CallbackBase *ovflwc, MemOperation mo) { MSHRit it = ms.find(calcLineAddr(paddr)); I(ovflwc); // for single MSHR, overflow handler REQUIRED! if(!overflow.empty()) { toOverflow(paddr, c, ovflwc, mo); return; } if(it == ms.end()) {// we must be overflowing because the issue did not happen toOverflow(paddr, c, ovflwc, mo); return; } I(it != ms.end()); if((*it).second.addRequest(paddr, c, mo)) { // ok, the addrequest succeeded, the request was added avgQueueSize.sample((*it).second.getPendingReqs() - 1); nOutsReqs++; #ifdef MSHR_BASICOCCSTATS if(mo == MemRead) occStats->incRdReqs(); #endif // there was no overflow, so the callback needs to be destroyed ovflwc->destroy(); // check to see if we have filled up the subentries checkSubEntries(paddr, mo); //MSG("[%llu] nFullRd=%d nFullWr=%d a:%lu",globalClock, // nFullReadEntries,nFullWriteEntries, calcLineAddr(paddr)); return; } else { // too many oustanding requests to the same line already. send to overflow toOverflow(paddr, c, ovflwc, mo); return; } }
void SingleMSHR<Addr_t, Cache_t>::checkOverflow() { if(overflow.empty()) //nothing to do return; if(checkingOverflow) // i am already checking the overflow return; I(!overflow.empty()); I(!checkingOverflow); checkingOverflow = true; int nConsumed = 0; do { OverflowField f = overflow.front(); MSHRit it = ms.find(calcLineAddr(f.paddr)); if(it == ms.end()) { if(nFreeEntries > 0) { ms[calcLineAddr(f.paddr)].firstRequest(f.paddr, calcLineAddr(f.paddr), nReads, nWrites, f.mo); checkSubEntries(f.paddr, f.mo); #ifdef MSHR_EXTRAOCCSTATS occStats->sampleEntry( calcLineAddr( f.paddr ) ); #endif bf.insert(calcLineAddr(f.paddr)); nFreeEntries--; updateOccHistogram(); nConsumed++; nOutsReqs++; if(f.mo == MemRead) occStats->incRdReqs(); f.ovflwcb->call(); f.cb->destroy(); overflow.pop_front(); nIssuesNewEntry.inc(); avgQueueSize.sample(0); } else { break; } } else { // just try to add the entry if((*it).second.addRequest(f.paddr, f.cb, f.mo)) { // succesfully accepted entry, but no need to call the callback // since there was already an entry pending for the same line avgQueueSize.sample((*it).second.getPendingReqs() - 1); f.ovflwcb->destroy(); overflow.pop_front(); nOutsReqs++; if(f.mo == MemRead) occStats->incRdReqs(); checkSubEntries(f.paddr, f.mo); //MSG("[%llu] nFullRd=%d nFullWr=%d a:%lu",globalClock, // nFullReadEntries,nFullWriteEntries,calcLineAddr(f.paddr)); } else { break; } } } while(!overflow.empty()); if(nConsumed) avgOverflowConsumptions.sample(nConsumed); checkingOverflow = false; }