mshr_queue.cc revision 5314
12623SN/A/* 22623SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 32623SN/A * All rights reserved. 42623SN/A * 52623SN/A * Redistribution and use in source and binary forms, with or without 62623SN/A * modification, are permitted provided that the following conditions are 72623SN/A * met: redistributions of source code must retain the above copyright 82623SN/A * notice, this list of conditions and the following disclaimer; 92623SN/A * redistributions in binary form must reproduce the above copyright 102623SN/A * notice, this list of conditions and the following disclaimer in the 112623SN/A * documentation and/or other materials provided with the distribution; 122623SN/A * neither the name of the copyright holders nor the names of its 132623SN/A * contributors may be used to endorse or promote products derived from 142623SN/A * this software without specific prior written permission. 152623SN/A * 162623SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172623SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182623SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192623SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202623SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212623SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222623SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232623SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242623SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252623SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262623SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Erik Hallnor 292623SN/A */ 302623SN/A 313170Sstever@eecs.umich.edu/** @file 322623SN/A * Definition of MSHRQueue class functions. 334040Ssaidi@eecs.umich.edu */ 342623SN/A 352623SN/A#include "mem/cache/miss/mshr_queue.hh" 363348Sbinkertn@umich.edu 373348Sbinkertn@umich.eduusing namespace std; 384762Snate@binkert.org 392901Ssaidi@eecs.umich.eduMSHRQueue::MSHRQueue(const std::string &_label, 402623SN/A int num_entries, int reserve, int _index) 412623SN/A : label(_label), 422623SN/A numEntries(num_entries + reserve - 1), numReserve(reserve), 432623SN/A index(_index) 442856Srdreslin@umich.edu{ 452856Srdreslin@umich.edu allocated = 0; 462856Srdreslin@umich.edu inServiceEntries = 0; 472856Srdreslin@umich.edu registers = new MSHR[numEntries]; 482856Srdreslin@umich.edu for (int i = 0; i < numEntries; ++i) { 492856Srdreslin@umich.edu registers[i].queue = this; 502856Srdreslin@umich.edu freeList.push_back(®isters[i]); 512856Srdreslin@umich.edu } 522856Srdreslin@umich.edu} 532856Srdreslin@umich.edu 542623SN/AMSHRQueue::~MSHRQueue() 552623SN/A{ 562623SN/A delete [] registers; 572623SN/A} 582623SN/A 592623SN/AMSHR * 602680Sktlim@umich.eduMSHRQueue::findMatch(Addr addr) const 612680Sktlim@umich.edu{ 622623SN/A MSHR::ConstIterator i = allocatedList.begin(); 632623SN/A MSHR::ConstIterator end = allocatedList.end(); 642680Sktlim@umich.edu for (; i != end; ++i) { 652623SN/A MSHR *mshr = *i; 662623SN/A if (mshr->addr == addr) { 672623SN/A return mshr; 682623SN/A } 692623SN/A } 703349Sbinkertn@umich.edu return NULL; 712623SN/A} 722623SN/A 732623SN/Abool 742623SN/AMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const 752623SN/A{ 762623SN/A // Need an empty vector 773349Sbinkertn@umich.edu assert(matches.empty()); 782623SN/A bool retval = false; 793184Srdreslin@umich.edu MSHR::ConstIterator i = allocatedList.begin(); 803184Srdreslin@umich.edu MSHR::ConstIterator end = allocatedList.end(); 812623SN/A for (; i != end; ++i) { 822623SN/A MSHR *mshr = *i; 832623SN/A if (mshr->addr == addr) { 842623SN/A retval = true; 852623SN/A matches.push_back(mshr); 863647Srdreslin@umich.edu } 873647Srdreslin@umich.edu } 883647Srdreslin@umich.edu return retval; 893647Srdreslin@umich.edu} 903647Srdreslin@umich.edu 912631SN/A 923647Srdreslin@umich.edubool 932631SN/AMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr) 942623SN/A{ 952623SN/A pkt->pushLabel(label); 962623SN/A MSHR::ConstIterator i = allocatedList.begin(); 972948Ssaidi@eecs.umich.edu MSHR::ConstIterator end = allocatedList.end(); 982948Ssaidi@eecs.umich.edu for (; i != end; ++i) { 993349Sbinkertn@umich.edu MSHR *mshr = *i; 1002948Ssaidi@eecs.umich.edu if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) { 1012948Ssaidi@eecs.umich.edu pkt->popLabel(); 1022948Ssaidi@eecs.umich.edu return true; 1032948Ssaidi@eecs.umich.edu } 1042948Ssaidi@eecs.umich.edu } 1052623SN/A pkt->popLabel(); 1063170Sstever@eecs.umich.edu return false; 1073170Sstever@eecs.umich.edu} 1082623SN/A 1092623SN/A 1103647Srdreslin@umich.eduMSHR * 1113647Srdreslin@umich.eduMSHRQueue::findPending(Addr addr, int size) const 1123647Srdreslin@umich.edu{ 1133647Srdreslin@umich.edu MSHR::ConstIterator i = readyList.begin(); 1142623SN/A MSHR::ConstIterator end = readyList.end(); 1152839Sktlim@umich.edu for (; i != end; ++i) { 1162867Sktlim@umich.edu MSHR *mshr = *i; 1173222Sktlim@umich.edu if (mshr->addr < addr) { 1182901Ssaidi@eecs.umich.edu if (mshr->addr + mshr->size > addr) { 1192623SN/A return mshr; 1202623SN/A } 1212623SN/A } else { 1222623SN/A if (addr + size > mshr->addr) { 1232623SN/A return mshr; 1242623SN/A } 1252623SN/A } 1262623SN/A } 1272623SN/A return NULL; 1282623SN/A} 1292915Sktlim@umich.edu 1302915Sktlim@umich.edu 1312623SN/AMSHR::Iterator 1322623SN/AMSHRQueue::addToReadyList(MSHR *mshr) 1332623SN/A{ 1342623SN/A if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) { 1352623SN/A return readyList.insert(readyList.end(), mshr); 1362623SN/A } 1372915Sktlim@umich.edu 1382915Sktlim@umich.edu MSHR::Iterator i = readyList.begin(); 1392623SN/A MSHR::Iterator end = readyList.end(); 1402798Sktlim@umich.edu for (; i != end; ++i) { 1412798Sktlim@umich.edu if ((*i)->readyTime > mshr->readyTime) { 1422901Ssaidi@eecs.umich.edu return readyList.insert(i, mshr); 1432839Sktlim@umich.edu } 1442798Sktlim@umich.edu } 1452839Sktlim@umich.edu assert(false); 1462798Sktlim@umich.edu return end; // keep stupid compilers happy 1472798Sktlim@umich.edu} 1482901Ssaidi@eecs.umich.edu 1492901Ssaidi@eecs.umich.edu 1502798Sktlim@umich.eduMSHR * 1512839Sktlim@umich.eduMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt, 1522839Sktlim@umich.edu Tick when, Counter order) 1532901Ssaidi@eecs.umich.edu{ 1542798Sktlim@umich.edu assert(!freeList.empty()); 1552623SN/A MSHR *mshr = freeList.front(); 1562623SN/A assert(mshr->getNumTargets() == 0); 1572623SN/A freeList.pop_front(); 1582798Sktlim@umich.edu 1592623SN/A mshr->allocate(addr, size, pkt, when, order); 1602798Sktlim@umich.edu mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 1614762Snate@binkert.org mshr->readyIter = addToReadyList(mshr); 1623201Shsul@eecs.umich.edu 1632867Sktlim@umich.edu allocated += 1; 1642867Sktlim@umich.edu return mshr; 1652915Sktlim@umich.edu} 1662915Sktlim@umich.edu 1672915Sktlim@umich.edu 1682867Sktlim@umich.eduvoid 1692867Sktlim@umich.eduMSHRQueue::deallocate(MSHR *mshr) 1702867Sktlim@umich.edu{ 1714471Sstever@eecs.umich.edu deallocateOne(mshr); 1722623SN/A} 1732798Sktlim@umich.edu 1742901Ssaidi@eecs.umich.eduMSHR::Iterator 1753222Sktlim@umich.eduMSHRQueue::deallocateOne(MSHR *mshr) 1762798Sktlim@umich.edu{ 1772798Sktlim@umich.edu MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 1782798Sktlim@umich.edu freeList.push_front(mshr); 1792798Sktlim@umich.edu allocated--; 1802798Sktlim@umich.edu if (mshr->inService) { 1812798Sktlim@umich.edu inServiceEntries--; 1822798Sktlim@umich.edu } else { 1833222Sktlim@umich.edu readyList.erase(mshr->readyIter); 1842867Sktlim@umich.edu } 1852867Sktlim@umich.edu mshr->deallocate(); 1862867Sktlim@umich.edu return retval; 1872867Sktlim@umich.edu} 1882867Sktlim@umich.edu 1892623SN/Avoid 1902623SN/AMSHRQueue::moveToFront(MSHR *mshr) 1912623SN/A{ 1922623SN/A if (!mshr->inService) { 1932623SN/A assert(mshr == *(mshr->readyIter)); 1942623SN/A readyList.erase(mshr->readyIter); 1954192Sktlim@umich.edu mshr->readyIter = readyList.insert(readyList.begin(), mshr); 1962623SN/A } 1972680Sktlim@umich.edu} 1982623SN/A 1992680Sktlim@umich.eduvoid 2002680Sktlim@umich.eduMSHRQueue::markInService(MSHR *mshr) 2012680Sktlim@umich.edu{ 2022623SN/A if (mshr->markInService()) { 2032623SN/A deallocate(mshr); 2042623SN/A } else { 2052623SN/A readyList.erase(mshr->readyIter); 2063201Shsul@eecs.umich.edu inServiceEntries += 1; 2073201Shsul@eecs.umich.edu } 2083201Shsul@eecs.umich.edu} 2093201Shsul@eecs.umich.edu 2102623SN/Avoid 2112623SN/AMSHRQueue::markPending(MSHR *mshr) 2122623SN/A{ 2132623SN/A assert(mshr->inService); 2142623SN/A mshr->inService = false; 2152623SN/A --inServiceEntries; 2162623SN/A /** 2172683Sktlim@umich.edu * @ todo might want to add rerequests to front of pending list for 2182623SN/A * performance. 2192623SN/A */ 2202623SN/A mshr->readyIter = addToReadyList(mshr); 2212623SN/A} 2222623SN/A 2233686Sktlim@umich.eduvoid 2242623SN/AMSHRQueue::squash(int threadNum) 2254471Sstever@eecs.umich.edu{ 2262623SN/A MSHR::Iterator i = allocatedList.begin(); 2272623SN/A MSHR::Iterator end = allocatedList.end(); 2282623SN/A for (; i != end;) { 2292623SN/A MSHR *mshr = *i; 2302623SN/A if (mshr->threadNum == threadNum) { 2312623SN/A while (mshr->hasTargets()) { 2322623SN/A mshr->popTarget(); 2332683Sktlim@umich.edu assert(0/*target->req->getThreadNum()*/ == threadNum); 2342623SN/A } 2352644Sstever@eecs.umich.edu assert(!mshr->hasTargets()); 2362623SN/A assert(mshr->ntargets==0); 2372644Sstever@eecs.umich.edu if (!mshr->inService) { 2382644Sstever@eecs.umich.edu i = deallocateOne(mshr); 2392623SN/A } else { 2402623SN/A //mshr->pkt->flags &= ~CACHE_LINE_FILL; 2412623SN/A ++i; 2422623SN/A } 2432623SN/A } else { 2442623SN/A ++i; 2452623SN/A } 2462623SN/A } 2472623SN/A} 2482623SN/A