mshr_queue.cc revision 4920
12810SN/A/* 22810SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 32810SN/A * All rights reserved. 42810SN/A * 52810SN/A * Redistribution and use in source and binary forms, with or without 62810SN/A * modification, are permitted provided that the following conditions are 72810SN/A * met: redistributions of source code must retain the above copyright 82810SN/A * notice, this list of conditions and the following disclaimer; 92810SN/A * redistributions in binary form must reproduce the above copyright 102810SN/A * notice, this list of conditions and the following disclaimer in the 112810SN/A * documentation and/or other materials provided with the distribution; 122810SN/A * neither the name of the copyright holders nor the names of its 132810SN/A * contributors may be used to endorse or promote products derived from 142810SN/A * this software without specific prior written permission. 152810SN/A * 162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272810SN/A * 282810SN/A * Authors: Erik Hallnor 292810SN/A */ 302810SN/A 312810SN/A/** @file 322810SN/A * Definition of MSHRQueue class functions. 332810SN/A */ 342810SN/A 352810SN/A#include "mem/cache/miss/mshr_queue.hh" 363348SN/A 373348SN/Ausing namespace std; 388232Snate@binkert.org 395338Sstever@gmail.comMSHRQueue::MSHRQueue(int num_entries, int reserve, int _index) 405338Sstever@gmail.com : numEntries(num_entries + reserve - 1), numReserve(reserve), 418786Sgblack@eecs.umich.edu index(_index) 422810SN/A{ 432810SN/A allocated = 0; 442810SN/A inServiceEntries = 0; 454965SN/A registers = new MSHR[numEntries]; 466122SSteve.Reinhardt@amd.com for (int i = 0; i < numEntries; ++i) { 475314SN/A registers[i].queue = this; 488736Sandreas.hansson@arm.com freeList.push_back(®isters[i]); 492810SN/A } 504475SN/A} 514475SN/A 524475SN/AMSHRQueue::~MSHRQueue() 535034SN/A{ 545034SN/A delete [] registers; 555314SN/A} 565314SN/A 574628SN/AMSHR * 585034SN/AMSHRQueue::findMatch(Addr addr) const 595034SN/A{ 605034SN/A MSHR::ConstIterator i = allocatedList.begin(); 616122SSteve.Reinhardt@amd.com MSHR::ConstIterator end = allocatedList.end(); 628134SAli.Saidi@ARM.com for (; i != end; ++i) { 634626SN/A MSHR *mshr = *i; 644626SN/A if (mshr->addr == addr) { 655034SN/A return mshr; 666122SSteve.Reinhardt@amd.com } 676978SLisa.Hsu@amd.com } 688833Sdam.sunwoo@arm.com return NULL; 694458SN/A} 702810SN/A 712810SN/Abool 725314SN/AMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const 735314SN/A{ 745314SN/A // Need an empty vector 755314SN/A assert(matches.empty()); 765314SN/A bool retval = false; 775314SN/A MSHR::ConstIterator i = allocatedList.begin(); 785314SN/A MSHR::ConstIterator end = allocatedList.end(); 795314SN/A for (; i != end; ++i) { 805314SN/A MSHR *mshr = *i; 815314SN/A if (mshr->addr == addr) { 825314SN/A retval = true; 836227Snate@binkert.org matches.push_back(mshr); 846227Snate@binkert.org } 852810SN/A } 862810SN/A return retval; 872810SN/A} 882810SN/A 893606SN/A 904458SN/Abool 914458SN/AMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr) 923013SN/A{ 933236SN/A MSHR::ConstIterator i = allocatedList.begin(); 944458SN/A MSHR::ConstIterator end = allocatedList.end(); 954458SN/A for (; i != end; ++i) { 964458SN/A MSHR *mshr = *i; 973246SN/A if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) { 983309SN/A return true; 993013SN/A } 1002810SN/A } 1012810SN/A return false; 1023013SN/A} 1033013SN/A 1042810SN/A 1053013SN/AMSHR * 1063013SN/AMSHRQueue::findPending(Addr addr, int size) const 1072810SN/A{ 1082810SN/A MSHR::ConstIterator i = readyList.begin(); 1092810SN/A MSHR::ConstIterator end = readyList.end(); 1102810SN/A for (; i != end; ++i) { 1112810SN/A MSHR *mshr = *i; 1123013SN/A if (mshr->addr < addr) { 1133013SN/A if (mshr->addr + mshr->size > addr) { 1143013SN/A return mshr; 1152897SN/A } 1162897SN/A } else { 1173013SN/A if (addr + size > mshr->addr) { 1182897SN/A return mshr; 1194666SN/A } 1204666SN/A } 1218708Sandreas.hansson@arm.com } 1222897SN/A return NULL; 1232810SN/A} 1242810SN/A 1252844SN/A 1262810SN/AMSHR::Iterator 1272858SN/AMSHRQueue::addToReadyList(MSHR *mshr) 1282858SN/A{ 1292858SN/A if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) { 1302858SN/A return readyList.insert(readyList.end(), mshr); 1318711Sandreas.hansson@arm.com } 1322858SN/A 1332858SN/A MSHR::Iterator i = readyList.begin(); 1344628SN/A MSHR::Iterator end = readyList.end(); 1352858SN/A for (; i != end; ++i) { 1362810SN/A if ((*i)->readyTime > mshr->readyTime) { 1372810SN/A return readyList.insert(i, mshr); 1382810SN/A } 1392810SN/A } 1402810SN/A assert(false); 1414022SN/A return end; // keep stupid compilers happy 1424022SN/A} 1434022SN/A 1442810SN/A 1452810SN/AMSHR * 1468833Sdam.sunwoo@arm.comMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt, 1472810SN/A Tick when, Counter order) 1482810SN/A{ 1492810SN/A assert(!freeList.empty()); 1502810SN/A MSHR *mshr = freeList.front(); 1518833Sdam.sunwoo@arm.com assert(mshr->getNumTargets() == 0); 1528833Sdam.sunwoo@arm.com freeList.pop_front(); 1538833Sdam.sunwoo@arm.com 1542810SN/A mshr->allocate(addr, size, pkt, when, order); 1552810SN/A mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 1564871SN/A mshr->readyIter = addToReadyList(mshr); 1574871SN/A 1584871SN/A allocated += 1; 1594871SN/A return mshr; 1604871SN/A} 1614871SN/A 1624871SN/A 1634871SN/Avoid 1644871SN/AMSHRQueue::deallocate(MSHR *mshr) 1654871SN/A{ 1662810SN/A deallocateOne(mshr); 1672810SN/A} 1682810SN/A 1698833Sdam.sunwoo@arm.comMSHR::Iterator 1702810SN/AMSHRQueue::deallocateOne(MSHR *mshr) 1714871SN/A{ 1728833Sdam.sunwoo@arm.com MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 1738833Sdam.sunwoo@arm.com freeList.push_front(mshr); 1748833Sdam.sunwoo@arm.com allocated--; 1752810SN/A if (mshr->inService) { 1762810SN/A inServiceEntries--; 1772810SN/A } else { 1782810SN/A readyList.erase(mshr->readyIter); 1798833Sdam.sunwoo@arm.com } 1802810SN/A mshr->deallocate(); 1814871SN/A return retval; 1828833Sdam.sunwoo@arm.com} 1838833Sdam.sunwoo@arm.com 1848833Sdam.sunwoo@arm.comvoid 1852810SN/AMSHRQueue::moveToFront(MSHR *mshr) 1862810SN/A{ 1874022SN/A if (!mshr->inService) { 1884022SN/A assert(mshr == *(mshr->readyIter)); 1894022SN/A readyList.erase(mshr->readyIter); 1902810SN/A mshr->readyIter = readyList.insert(readyList.begin(), mshr); 1912810SN/A } 1928833Sdam.sunwoo@arm.com} 1932810SN/A 1942810SN/Avoid 1952810SN/AMSHRQueue::markInService(MSHR *mshr) 1962810SN/A{ 1978833Sdam.sunwoo@arm.com if (mshr->markInService()) { 1988833Sdam.sunwoo@arm.com deallocate(mshr); 1998833Sdam.sunwoo@arm.com } else { 2002810SN/A readyList.erase(mshr->readyIter); 2012810SN/A inServiceEntries += 1; 2022810SN/A } 2032810SN/A} 2042810SN/A 2058833Sdam.sunwoo@arm.comvoid 2062810SN/AMSHRQueue::markPending(MSHR *mshr) 2074871SN/A{ 2088833Sdam.sunwoo@arm.com assert(mshr->inService); 2098833Sdam.sunwoo@arm.com mshr->inService = false; 2108833Sdam.sunwoo@arm.com --inServiceEntries; 2112810SN/A /** 2122810SN/A * @ todo might want to add rerequests to front of pending list for 2132810SN/A * performance. 2142810SN/A */ 2158833Sdam.sunwoo@arm.com mshr->readyIter = addToReadyList(mshr); 2162810SN/A} 2174871SN/A 2188833Sdam.sunwoo@arm.comvoid 2198833Sdam.sunwoo@arm.comMSHRQueue::squash(int threadNum) 2208833Sdam.sunwoo@arm.com{ 2212810SN/A MSHR::Iterator i = allocatedList.begin(); 2222810SN/A MSHR::Iterator end = allocatedList.end(); 2234022SN/A for (; i != end;) { 2244022SN/A MSHR *mshr = *i; 2254022SN/A if (mshr->threadNum == threadNum) { 2262810SN/A while (mshr->hasTargets()) { 2272810SN/A mshr->popTarget(); 2288833Sdam.sunwoo@arm.com assert(0/*target->req->getThreadNum()*/ == threadNum); 2292810SN/A } 2302810SN/A assert(!mshr->hasTargets()); 2312810SN/A assert(mshr->ntargets==0); 2322810SN/A if (!mshr->inService) { 2338833Sdam.sunwoo@arm.com i = deallocateOne(mshr); 2348833Sdam.sunwoo@arm.com } else { 2358833Sdam.sunwoo@arm.com //mshr->pkt->flags &= ~CACHE_LINE_FILL; 2362810SN/A ++i; 2372810SN/A } 2382810SN/A } else { 2392810SN/A ++i; 2402810SN/A } 2418833Sdam.sunwoo@arm.com } 2422810SN/A} 2434871SN/A