mshr_queue.cc revision 4871
18092Snilay@cs.wisc.edu/* 28092Snilay@cs.wisc.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan 38092Snilay@cs.wisc.edu * All rights reserved. 48092Snilay@cs.wisc.edu * 58092Snilay@cs.wisc.edu * Redistribution and use in source and binary forms, with or without 68092Snilay@cs.wisc.edu * modification, are permitted provided that the following conditions are 78092Snilay@cs.wisc.edu * met: redistributions of source code must retain the above copyright 88092Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer; 98092Snilay@cs.wisc.edu * redistributions in binary form must reproduce the above copyright 108092Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer in the 118092Snilay@cs.wisc.edu * documentation and/or other materials provided with the distribution; 128092Snilay@cs.wisc.edu * neither the name of the copyright holders nor the names of its 138092Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from 148092Snilay@cs.wisc.edu * this software without specific prior written permission. 158092Snilay@cs.wisc.edu * 168092Snilay@cs.wisc.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 178092Snilay@cs.wisc.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 188092Snilay@cs.wisc.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 198092Snilay@cs.wisc.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 208092Snilay@cs.wisc.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 218092Snilay@cs.wisc.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 228092Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 238092Snilay@cs.wisc.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 248092Snilay@cs.wisc.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 258092Snilay@cs.wisc.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 268092Snilay@cs.wisc.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 278092Snilay@cs.wisc.edu * 288092Snilay@cs.wisc.edu * Authors: Erik Hallnor 298092Snilay@cs.wisc.edu */ 308092Snilay@cs.wisc.edu 318092Snilay@cs.wisc.edu/** @file 328092Snilay@cs.wisc.edu * Definition of MSHRQueue class functions. 338092Snilay@cs.wisc.edu */ 348092Snilay@cs.wisc.edu 358164Snilay@cs.wisc.edu#include "mem/cache/miss/mshr_queue.hh" 368165Snilay@cs.wisc.edu 378092Snilay@cs.wisc.eduusing namespace std; 388092Snilay@cs.wisc.edu 398092Snilay@cs.wisc.eduMSHRQueue::MSHRQueue(int num_entries, int reserve, int _index) 408092Snilay@cs.wisc.edu : numEntries(num_entries + reserve - 1), numReserve(reserve), 418092Snilay@cs.wisc.edu index(_index) 428092Snilay@cs.wisc.edu{ 438174Snilay@cs.wisc.edu allocated = 0; 448092Snilay@cs.wisc.edu inServiceEntries = 0; 458092Snilay@cs.wisc.edu registers = new MSHR[numEntries]; 468174Snilay@cs.wisc.edu for (int i = 0; i < numEntries; ++i) { 478174Snilay@cs.wisc.edu registers[i].queue = this; 488174Snilay@cs.wisc.edu freeList.push_back(®isters[i]); 498174Snilay@cs.wisc.edu } 508174Snilay@cs.wisc.edu} 518174Snilay@cs.wisc.edu 528174Snilay@cs.wisc.eduMSHRQueue::~MSHRQueue() 538092Snilay@cs.wisc.edu{ 548092Snilay@cs.wisc.edu delete [] registers; 558188SLisa.Hsu@amd.com} 568092Snilay@cs.wisc.edu 578092Snilay@cs.wisc.eduMSHR * 588174Snilay@cs.wisc.eduMSHRQueue::findMatch(Addr addr) const 598174Snilay@cs.wisc.edu{ 608174Snilay@cs.wisc.edu MSHR::ConstIterator i = allocatedList.begin(); 618174Snilay@cs.wisc.edu MSHR::ConstIterator end = allocatedList.end(); 628174Snilay@cs.wisc.edu for (; i != end; ++i) { 638174Snilay@cs.wisc.edu MSHR *mshr = *i; 648174Snilay@cs.wisc.edu if (mshr->addr == addr) { 658174Snilay@cs.wisc.edu return mshr; 668174Snilay@cs.wisc.edu } 678174Snilay@cs.wisc.edu } 688092Snilay@cs.wisc.edu return NULL; 698092Snilay@cs.wisc.edu} 708188SLisa.Hsu@amd.com 718174Snilay@cs.wisc.edubool 728174Snilay@cs.wisc.eduMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const 738174Snilay@cs.wisc.edu{ 748174Snilay@cs.wisc.edu // Need an empty vector 758174Snilay@cs.wisc.edu assert(matches.empty()); 768174Snilay@cs.wisc.edu bool retval = false; 778174Snilay@cs.wisc.edu MSHR::ConstIterator i = allocatedList.begin(); 788174Snilay@cs.wisc.edu MSHR::ConstIterator end = allocatedList.end(); 798174Snilay@cs.wisc.edu for (; i != end; ++i) { 808174Snilay@cs.wisc.edu MSHR *mshr = *i; 818174Snilay@cs.wisc.edu if (mshr->addr == addr) { 828174Snilay@cs.wisc.edu retval = true; 838174Snilay@cs.wisc.edu matches.push_back(mshr); 848174Snilay@cs.wisc.edu } 858174Snilay@cs.wisc.edu } 868174Snilay@cs.wisc.edu return retval; 878174Snilay@cs.wisc.edu 888174Snilay@cs.wisc.edu} 898174Snilay@cs.wisc.edu 908174Snilay@cs.wisc.eduMSHR * 918174Snilay@cs.wisc.eduMSHRQueue::findPending(Addr addr, int size) const 928174Snilay@cs.wisc.edu{ 938174Snilay@cs.wisc.edu MSHR::ConstIterator i = readyList.begin(); 948174Snilay@cs.wisc.edu MSHR::ConstIterator end = readyList.end(); 958174Snilay@cs.wisc.edu for (; i != end; ++i) { 968174Snilay@cs.wisc.edu MSHR *mshr = *i; 978174Snilay@cs.wisc.edu if (mshr->addr < addr) { 988174Snilay@cs.wisc.edu if (mshr->addr + mshr->size > addr) { 998174Snilay@cs.wisc.edu return mshr; 1008174Snilay@cs.wisc.edu } 1018174Snilay@cs.wisc.edu } else { 1028174Snilay@cs.wisc.edu if (addr + size > mshr->addr) { 1038174Snilay@cs.wisc.edu return mshr; 1048174Snilay@cs.wisc.edu } 1058174Snilay@cs.wisc.edu } 1068174Snilay@cs.wisc.edu } 1078174Snilay@cs.wisc.edu return NULL; 1088174Snilay@cs.wisc.edu} 1098174Snilay@cs.wisc.edu 1108174Snilay@cs.wisc.edu 1118174Snilay@cs.wisc.eduMSHR::Iterator 1128174Snilay@cs.wisc.eduMSHRQueue::addToReadyList(MSHR *mshr) 1138174Snilay@cs.wisc.edu{ 1148174Snilay@cs.wisc.edu if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) { 1158174Snilay@cs.wisc.edu return readyList.insert(readyList.end(), mshr); 1168174Snilay@cs.wisc.edu } 1178174Snilay@cs.wisc.edu 1188174Snilay@cs.wisc.edu MSHR::Iterator i = readyList.begin(); 1198174Snilay@cs.wisc.edu MSHR::Iterator end = readyList.end(); 1208174Snilay@cs.wisc.edu for (; i != end; ++i) { 1218174Snilay@cs.wisc.edu if ((*i)->readyTime > mshr->readyTime) { 1228174Snilay@cs.wisc.edu return readyList.insert(i, mshr); 1238174Snilay@cs.wisc.edu } 1248174Snilay@cs.wisc.edu } 1258174Snilay@cs.wisc.edu assert(false); 1268174Snilay@cs.wisc.edu} 1278174Snilay@cs.wisc.edu 1288174Snilay@cs.wisc.edu 1298092Snilay@cs.wisc.eduMSHR * 1308092Snilay@cs.wisc.eduMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt, 1318092Snilay@cs.wisc.edu Tick when, Counter order) 1328092Snilay@cs.wisc.edu{ 1338174Snilay@cs.wisc.edu assert(!freeList.empty()); 1348174Snilay@cs.wisc.edu MSHR *mshr = freeList.front(); 1358174Snilay@cs.wisc.edu assert(mshr->getNumTargets() == 0); 1368174Snilay@cs.wisc.edu freeList.pop_front(); 1378174Snilay@cs.wisc.edu 1388174Snilay@cs.wisc.edu mshr->allocate(addr, size, pkt, when, order); 1398174Snilay@cs.wisc.edu mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 1408092Snilay@cs.wisc.edu mshr->readyIter = addToReadyList(mshr); 1418092Snilay@cs.wisc.edu 142 allocated += 1; 143 return mshr; 144} 145 146 147void 148MSHRQueue::deallocate(MSHR *mshr) 149{ 150 deallocateOne(mshr); 151} 152 153MSHR::Iterator 154MSHRQueue::deallocateOne(MSHR *mshr) 155{ 156 MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 157 freeList.push_front(mshr); 158 allocated--; 159 if (mshr->inService) { 160 inServiceEntries--; 161 } else { 162 readyList.erase(mshr->readyIter); 163 } 164 mshr->deallocate(); 165 return retval; 166} 167 168void 169MSHRQueue::moveToFront(MSHR *mshr) 170{ 171 if (!mshr->inService) { 172 assert(mshr == *(mshr->readyIter)); 173 readyList.erase(mshr->readyIter); 174 mshr->readyIter = readyList.insert(readyList.begin(), mshr); 175 } 176} 177 178void 179MSHRQueue::markInService(MSHR *mshr) 180{ 181 assert(!mshr->inService); 182 if (mshr->isSimpleForward()) { 183 // we just forwarded the request packet & don't expect a 184 // response, so get rid of it 185 assert(mshr->getNumTargets() == 1); 186 mshr->popTarget(); 187 deallocate(mshr); 188 return; 189 } 190 mshr->inService = true; 191 readyList.erase(mshr->readyIter); 192 //mshr->readyIter = NULL; 193 inServiceEntries += 1; 194 //readyList.pop_front(); 195} 196 197void 198MSHRQueue::markPending(MSHR *mshr) 199{ 200 assert(mshr->inService); 201 mshr->inService = false; 202 --inServiceEntries; 203 /** 204 * @ todo might want to add rerequests to front of pending list for 205 * performance. 206 */ 207 mshr->readyIter = addToReadyList(mshr); 208} 209 210void 211MSHRQueue::squash(int threadNum) 212{ 213 MSHR::Iterator i = allocatedList.begin(); 214 MSHR::Iterator end = allocatedList.end(); 215 for (; i != end;) { 216 MSHR *mshr = *i; 217 if (mshr->threadNum == threadNum) { 218 while (mshr->hasTargets()) { 219 mshr->popTarget(); 220 assert(0/*target->req->getThreadNum()*/ == threadNum); 221 } 222 assert(!mshr->hasTargets()); 223 assert(mshr->ntargets==0); 224 if (!mshr->inService) { 225 i = deallocateOne(mshr); 226 } else { 227 //mshr->pkt->flags &= ~CACHE_LINE_FILL; 228 ++i; 229 } 230 } else { 231 ++i; 232 } 233 } 234} 235