mshr_queue.cc revision 4920
12SN/A/* 21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 32SN/A * All rights reserved. 42SN/A * 52SN/A * Redistribution and use in source and binary forms, with or without 62SN/A * modification, are permitted provided that the following conditions are 72SN/A * met: redistributions of source code must retain the above copyright 82SN/A * notice, this list of conditions and the following disclaimer; 92SN/A * redistributions in binary form must reproduce the above copyright 102SN/A * notice, this list of conditions and the following disclaimer in the 112SN/A * documentation and/or other materials provided with the distribution; 122SN/A * neither the name of the copyright holders nor the names of its 132SN/A * contributors may be used to endorse or promote products derived from 142SN/A * this software without specific prior written permission. 152SN/A * 162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665SN/A * 282665SN/A * Authors: Erik Hallnor 292SN/A */ 302SN/A 312SN/A/** @file 322SN/A * Definition of MSHRQueue class functions. 336214Snate@binkert.org */ 342SN/A 352SN/A#include "mem/cache/miss/mshr_queue.hh" 362SN/A 376214Snate@binkert.orgusing namespace std; 386214Snate@binkert.org 392SN/AMSHRQueue::MSHRQueue(int num_entries, int reserve, int _index) 402SN/A : numEntries(num_entries + reserve - 1), numReserve(reserve), 412SN/A index(_index) 429180Sandreas.hansson@arm.com{ 4310474Sandreas.hansson@arm.com allocated = 0; 449500Snilay@cs.wisc.edu inServiceEntries = 0; 4511004SAndreas.Sandberg@ARM.com registers = new MSHR[numEntries]; 469180Sandreas.hansson@arm.com for (int i = 0; i < numEntries; ++i) { 4710276SAndreas.Sandberg@ARM.com registers[i].queue = this; 4810276SAndreas.Sandberg@ARM.com freeList.push_back(®isters[i]); 492SN/A } 505543SN/A} 512SN/A 525543SN/AMSHRQueue::~MSHRQueue() 532SN/A{ 542SN/A delete [] registers; 552SN/A} 562SN/A 572SN/AMSHR * 582SN/AMSHRQueue::findMatch(Addr addr) const 592SN/A{ 602SN/A MSHR::ConstIterator i = allocatedList.begin(); 619158Sandreas.hansson@arm.com MSHR::ConstIterator end = allocatedList.end(); 622SN/A for (; i != end; ++i) { 639158Sandreas.hansson@arm.com MSHR *mshr = *i; 642SN/A if (mshr->addr == addr) { 659158Sandreas.hansson@arm.com return mshr; 662667SN/A } 672130SN/A } 689180Sandreas.hansson@arm.com return NULL; 699180Sandreas.hansson@arm.com} 709180Sandreas.hansson@arm.com 719180Sandreas.hansson@arm.combool 729180Sandreas.hansson@arm.comMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const 739180Sandreas.hansson@arm.com{ 749180Sandreas.hansson@arm.com // Need an empty vector 759180Sandreas.hansson@arm.com assert(matches.empty()); 7611990Sandreas.sandberg@arm.com bool retval = false; 779180Sandreas.hansson@arm.com MSHR::ConstIterator i = allocatedList.begin(); 789180Sandreas.hansson@arm.com MSHR::ConstIterator end = allocatedList.end(); 799180Sandreas.hansson@arm.com for (; i != end; ++i) { 809180Sandreas.hansson@arm.com MSHR *mshr = *i; 819180Sandreas.hansson@arm.com if (mshr->addr == addr) { 829180Sandreas.hansson@arm.com retval = true; 839180Sandreas.hansson@arm.com matches.push_back(mshr); 849180Sandreas.hansson@arm.com } 859180Sandreas.hansson@arm.com } 869180Sandreas.hansson@arm.com return retval; 879180Sandreas.hansson@arm.com} 889180Sandreas.hansson@arm.com 899180Sandreas.hansson@arm.com 909180Sandreas.hansson@arm.combool 919180Sandreas.hansson@arm.comMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr) 929180Sandreas.hansson@arm.com{ 939180Sandreas.hansson@arm.com MSHR::ConstIterator i = allocatedList.begin(); 9411004SAndreas.Sandberg@ARM.com MSHR::ConstIterator end = allocatedList.end(); 959180Sandreas.hansson@arm.com for (; i != end; ++i) { 969184Sandreas.hansson@arm.com MSHR *mshr = *i; 979184Sandreas.hansson@arm.com if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) { 989184Sandreas.hansson@arm.com return true; 999180Sandreas.hansson@arm.com } 10011004SAndreas.Sandberg@ARM.com } 1019180Sandreas.hansson@arm.com return false; 1029180Sandreas.hansson@arm.com} 1039180Sandreas.hansson@arm.com 1049180Sandreas.hansson@arm.com 1059180Sandreas.hansson@arm.comMSHR * 1069180Sandreas.hansson@arm.comMSHRQueue::findPending(Addr addr, int size) const 1079180Sandreas.hansson@arm.com{ 1089180Sandreas.hansson@arm.com MSHR::ConstIterator i = readyList.begin(); 1099180Sandreas.hansson@arm.com MSHR::ConstIterator end = readyList.end(); 1109180Sandreas.hansson@arm.com for (; i != end; ++i) { 11111004SAndreas.Sandberg@ARM.com MSHR *mshr = *i; 1129180Sandreas.hansson@arm.com if (mshr->addr < addr) { 1139180Sandreas.hansson@arm.com if (mshr->addr + mshr->size > addr) { 1149180Sandreas.hansson@arm.com return mshr; 11511004SAndreas.Sandberg@ARM.com } 1169180Sandreas.hansson@arm.com } else { 1179180Sandreas.hansson@arm.com if (addr + size > mshr->addr) { 11811004SAndreas.Sandberg@ARM.com return mshr; 1199498Snilay@cs.wisc.edu } 1209498Snilay@cs.wisc.edu } 12111004SAndreas.Sandberg@ARM.com } 12211004SAndreas.Sandberg@ARM.com return NULL; 12311004SAndreas.Sandberg@ARM.com} 12411004SAndreas.Sandberg@ARM.com 12511004SAndreas.Sandberg@ARM.com 1269498Snilay@cs.wisc.eduMSHR::Iterator 12711004SAndreas.Sandberg@ARM.comMSHRQueue::addToReadyList(MSHR *mshr) 1289498Snilay@cs.wisc.edu{ 1299498Snilay@cs.wisc.edu if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) { 13011004SAndreas.Sandberg@ARM.com return readyList.insert(readyList.end(), mshr); 1319498Snilay@cs.wisc.edu } 1329498Snilay@cs.wisc.edu 1339500Snilay@cs.wisc.edu MSHR::Iterator i = readyList.begin(); 1349180Sandreas.hansson@arm.com MSHR::Iterator end = readyList.end(); 1359180Sandreas.hansson@arm.com for (; i != end; ++i) { 1369180Sandreas.hansson@arm.com if ((*i)->readyTime > mshr->readyTime) { 1372130SN/A return readyList.insert(i, mshr); 1382130SN/A } 1392130SN/A } 1402130SN/A assert(false); 1412130SN/A return end; // keep stupid compilers happy 1422130SN/A} 1432130SN/A 1447720Sgblack@eecs.umich.edu 1457720Sgblack@eecs.umich.eduMSHR * 1467720Sgblack@eecs.umich.eduMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt, 1477720Sgblack@eecs.umich.edu Tick when, Counter order) 1487720Sgblack@eecs.umich.edu{ 1497720Sgblack@eecs.umich.edu assert(!freeList.empty()); 1507720Sgblack@eecs.umich.edu MSHR *mshr = freeList.front(); 1517720Sgblack@eecs.umich.edu assert(mshr->getNumTargets() == 0); 1527720Sgblack@eecs.umich.edu freeList.pop_front(); 1537720Sgblack@eecs.umich.edu 1547720Sgblack@eecs.umich.edu mshr->allocate(addr, size, pkt, when, order); 1557720Sgblack@eecs.umich.edu mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 1567720Sgblack@eecs.umich.edu mshr->readyIter = addToReadyList(mshr); 1577720Sgblack@eecs.umich.edu 1587720Sgblack@eecs.umich.edu allocated += 1; 1597720Sgblack@eecs.umich.edu return mshr; 1607720Sgblack@eecs.umich.edu} 1617720Sgblack@eecs.umich.edu 1627720Sgblack@eecs.umich.edu 1637720Sgblack@eecs.umich.eduvoid 1647720Sgblack@eecs.umich.eduMSHRQueue::deallocate(MSHR *mshr) 1657720Sgblack@eecs.umich.edu{ 1662438SN/A deallocateOne(mshr); 1672438SN/A} 1686221Snate@binkert.org 1696221Snate@binkert.orgMSHR::Iterator 1706221Snate@binkert.orgMSHRQueue::deallocateOne(MSHR *mshr) 1716221Snate@binkert.org{ 1726221Snate@binkert.org MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 1736221Snate@binkert.org freeList.push_front(mshr); 17411005Sandreas.sandberg@arm.com allocated--; 17511005Sandreas.sandberg@arm.com if (mshr->inService) { 17611005Sandreas.sandberg@arm.com inServiceEntries--; 17711005Sandreas.sandberg@arm.com } else { 1789031Sandreas.hansson@arm.com readyList.erase(mshr->readyIter); 1799031Sandreas.hansson@arm.com } 1809031Sandreas.hansson@arm.com mshr->deallocate(); 1819031Sandreas.hansson@arm.com return retval; 1829031Sandreas.hansson@arm.com} 1839031Sandreas.hansson@arm.com 1847678Sgblack@eecs.umich.eduvoid 18510474Sandreas.hansson@arm.comMSHRQueue::moveToFront(MSHR *mshr) 18610474Sandreas.hansson@arm.com{ 18710474Sandreas.hansson@arm.com if (!mshr->inService) { 18810474Sandreas.hansson@arm.com assert(mshr == *(mshr->readyIter)); 18910474Sandreas.hansson@arm.com readyList.erase(mshr->readyIter); 1907678Sgblack@eecs.umich.edu mshr->readyIter = readyList.insert(readyList.begin(), mshr); 19111306Santhony.gutierrez@amd.com } 19211306Santhony.gutierrez@amd.com} 19311306Santhony.gutierrez@amd.com 19411306Santhony.gutierrez@amd.comvoid 19511306Santhony.gutierrez@amd.comMSHRQueue::markInService(MSHR *mshr) 19611306Santhony.gutierrez@amd.com{ 19711306Santhony.gutierrez@amd.com if (mshr->markInService()) { 19811306Santhony.gutierrez@amd.com deallocate(mshr); 19911306Santhony.gutierrez@amd.com } else { 20011306Santhony.gutierrez@amd.com readyList.erase(mshr->readyIter); 20111306Santhony.gutierrez@amd.com inServiceEntries += 1; 20211306Santhony.gutierrez@amd.com } 20311306Santhony.gutierrez@amd.com} 20410839Sandreas.sandberg@arm.com 20510839Sandreas.sandberg@arm.comvoid 20610839Sandreas.sandberg@arm.comMSHRQueue::markPending(MSHR *mshr) 20710839Sandreas.sandberg@arm.com{ 20810839Sandreas.sandberg@arm.com assert(mshr->inService); 2096214Snate@binkert.org mshr->inService = false; 210 --inServiceEntries; 211 /** 212 * @ todo might want to add rerequests to front of pending list for 213 * performance. 214 */ 215 mshr->readyIter = addToReadyList(mshr); 216} 217 218void 219MSHRQueue::squash(int threadNum) 220{ 221 MSHR::Iterator i = allocatedList.begin(); 222 MSHR::Iterator end = allocatedList.end(); 223 for (; i != end;) { 224 MSHR *mshr = *i; 225 if (mshr->threadNum == threadNum) { 226 while (mshr->hasTargets()) { 227 mshr->popTarget(); 228 assert(0/*target->req->getThreadNum()*/ == threadNum); 229 } 230 assert(!mshr->hasTargets()); 231 assert(mshr->ntargets==0); 232 if (!mshr->inService) { 233 i = deallocateOne(mshr); 234 } else { 235 //mshr->pkt->flags &= ~CACHE_LINE_FILL; 236 ++i; 237 } 238 } else { 239 ++i; 240 } 241 } 242} 243