mshr_queue.cc revision 3149
12292SN/A/* 22689Sktlim@umich.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan 32292SN/A * All rights reserved. 42292SN/A * 52292SN/A * Redistribution and use in source and binary forms, with or without 62292SN/A * modification, are permitted provided that the following conditions are 72292SN/A * met: redistributions of source code must retain the above copyright 82292SN/A * notice, this list of conditions and the following disclaimer; 92292SN/A * redistributions in binary form must reproduce the above copyright 102292SN/A * notice, this list of conditions and the following disclaimer in the 112292SN/A * documentation and/or other materials provided with the distribution; 122292SN/A * neither the name of the copyright holders nor the names of its 132292SN/A * contributors may be used to endorse or promote products derived from 142292SN/A * this software without specific prior written permission. 152292SN/A * 162292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272689Sktlim@umich.edu * 282689Sktlim@umich.edu * Authors: Erik Hallnor 292292SN/A */ 302292SN/A 312292SN/A/** @file 322292SN/A * Definition of the MSHRQueue. 332292SN/A */ 342292SN/A 352292SN/A#include "mem/cache/miss/mshr_queue.hh" 362292SN/A#include "sim/eventq.hh" 372292SN/A 382292SN/Ausing namespace std; 392292SN/A 402669Sktlim@umich.eduMSHRQueue::MSHRQueue(int num_mshrs, int reserve) 415034Smilesck@eecs.umich.edu : numMSHRs(num_mshrs + reserve - 1), numReserve(reserve) 422292SN/A{ 432292SN/A allocated = 0; 442292SN/A inServiceMSHRs = 0; 452292SN/A allocatedTargets = 0; 462292SN/A registers = new MSHR[numMSHRs]; 472292SN/A for (int i = 0; i < numMSHRs; ++i) { 482292SN/A freeList.push_back(®isters[i]); 492292SN/A } 502292SN/A} 512292SN/A 522292SN/AMSHRQueue::~MSHRQueue() 532292SN/A{ 542292SN/A delete [] registers; 552292SN/A} 562292SN/A 572292SN/AMSHR* 582292SN/AMSHRQueue::findMatch(Addr addr) const 592292SN/A{ 602292SN/A MSHR::ConstIterator i = allocatedList.begin(); 612292SN/A MSHR::ConstIterator end = allocatedList.end(); 622292SN/A for (; i != end; ++i) { 632292SN/A MSHR *mshr = *i; 642292SN/A if (mshr->addr == addr) { 652292SN/A return mshr; 662292SN/A } 672292SN/A } 682292SN/A return NULL; 692292SN/A} 702292SN/A 712292SN/Abool 722292SN/AMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const 732292SN/A{ 742292SN/A // Need an empty vector 752292SN/A assert(matches.empty()); 762292SN/A bool retval = false; 772292SN/A MSHR::ConstIterator i = allocatedList.begin(); 782292SN/A MSHR::ConstIterator end = allocatedList.end(); 792292SN/A for (; i != end; ++i) { 802292SN/A MSHR *mshr = *i; 812292SN/A if (mshr->addr == addr) { 822292SN/A retval = true; 832292SN/A matches.push_back(mshr); 842292SN/A } 852292SN/A } 862292SN/A return retval; 872292SN/A 882292SN/A} 892292SN/A 902292SN/AMSHR* 912292SN/AMSHRQueue::findPending(Packet * &pkt) const 922292SN/A{ 932292SN/A MSHR::ConstIterator i = pendingList.begin(); 942292SN/A MSHR::ConstIterator end = pendingList.end(); 952292SN/A for (; i != end; ++i) { 962292SN/A MSHR *mshr = *i; 972292SN/A if (mshr->addr < pkt->getAddr()) { 982292SN/A if (mshr->addr + mshr->pkt->getSize() > pkt->getAddr()) { 992292SN/A return mshr; 1002292SN/A } 1012292SN/A } else { 1022292SN/A if (pkt->getAddr() + pkt->getSize() > mshr->addr) { 1032292SN/A return mshr; 1042292SN/A } 1052292SN/A } 1062292SN/A 1072292SN/A //need to check destination address for copies. 1082292SN/A //TEMP NOT DOING COPIES 1092292SN/A#if 0 1102292SN/A if (mshr->pkt->cmd == Copy) { 1112292SN/A Addr dest = mshr->pkt->dest; 1122292SN/A if (dest < pkt->addr) { 1132292SN/A if (dest + mshr->pkt->size > pkt->addr) { 1142292SN/A return mshr; 1152292SN/A } 1162292SN/A } else { 1172292SN/A if (pkt->addr + pkt->size > dest) { 1182292SN/A return mshr; 1192292SN/A } 1205034Smilesck@eecs.umich.edu } 1212292SN/A } 1225034Smilesck@eecs.umich.edu#endif 1232292SN/A } 1242292SN/A return NULL; 1252292SN/A} 1262292SN/A 1272292SN/AMSHR* 1282292SN/AMSHRQueue::allocate(Packet * &pkt, int size) 1292292SN/A{ 1302292SN/A Addr aligned_addr = pkt->getAddr() & ~((Addr)size - 1); 1312292SN/A assert(!freeList.empty()); 1322292SN/A MSHR *mshr = freeList.front(); 1332292SN/A assert(mshr->getNumTargets() == 0); 1342292SN/A freeList.pop_front(); 1352292SN/A 1362292SN/A if (!pkt->needsResponse()) { 1372292SN/A mshr->allocateAsBuffer(pkt); 1382292SN/A } else { 1392292SN/A assert(size !=0); 1402327SN/A mshr->allocate(pkt->cmd, aligned_addr, size, pkt); 1412292SN/A allocatedTargets += 1; 1422292SN/A } 1432292SN/A mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 1442292SN/A mshr->readyIter = pendingList.insert(pendingList.end(), mshr); 1452292SN/A 1462292SN/A allocated += 1; 1472292SN/A return mshr; 1482292SN/A} 1492292SN/A 1502292SN/AMSHR* 1512292SN/AMSHRQueue::allocateFetch(Addr addr, int size, Packet * &target) 1522292SN/A{ 1532292SN/A MSHR *mshr = freeList.front(); 1542292SN/A assert(mshr->getNumTargets() == 0); 1552292SN/A freeList.pop_front(); 1562292SN/A mshr->allocate(Packet::ReadReq, addr, size, target); 1572292SN/A mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 1582292SN/A mshr->readyIter = pendingList.insert(pendingList.end(), mshr); 1592292SN/A 1602307SN/A allocated += 1; 1612348SN/A return mshr; 1622307SN/A} 1632348SN/A 1642348SN/AMSHR* 1652307SN/AMSHRQueue::allocateTargetList(Addr addr, int size) 1662292SN/A{ 1672292SN/A MSHR *mshr = freeList.front(); 1682292SN/A assert(mshr->getNumTargets() == 0); 169 freeList.pop_front(); 170 Packet * dummy; 171 mshr->allocate(Packet::ReadReq, addr, size, dummy); 172 mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 173 mshr->inService = true; 174 ++inServiceMSHRs; 175 ++allocated; 176 return mshr; 177} 178 179 180void 181MSHRQueue::deallocate(MSHR* mshr) 182{ 183 deallocateOne(mshr); 184} 185 186MSHR::Iterator 187MSHRQueue::deallocateOne(MSHR* mshr) 188{ 189 MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 190 freeList.push_front(mshr); 191 allocated--; 192 allocatedTargets -= mshr->getNumTargets(); 193 if (mshr->inService) { 194 inServiceMSHRs--; 195 } else { 196 pendingList.erase(mshr->readyIter); 197 } 198 mshr->deallocate(); 199 return retval; 200} 201 202void 203MSHRQueue::moveToFront(MSHR *mshr) 204{ 205 if (!mshr->inService) { 206 assert(mshr == *(mshr->readyIter)); 207 pendingList.erase(mshr->readyIter); 208 mshr->readyIter = pendingList.insert(pendingList.begin(), mshr); 209 } 210} 211 212void 213MSHRQueue::markInService(MSHR* mshr) 214{ 215 //assert(mshr == pendingList.front()); 216 if (!mshr->pkt->needsResponse()) { 217 assert(mshr->getNumTargets() == 0); 218 deallocate(mshr); 219 return; 220 } 221 mshr->inService = true; 222 pendingList.erase(mshr->readyIter); 223 //mshr->readyIter = NULL; 224 inServiceMSHRs += 1; 225 //pendingList.pop_front(); 226} 227 228void 229MSHRQueue::markPending(MSHR* mshr, Packet::Command cmd) 230{ 231 //assert(mshr->readyIter == NULL); 232 mshr->pkt->cmd = cmd; 233 mshr->pkt->flags &= ~SATISFIED; 234 mshr->inService = false; 235 --inServiceMSHRs; 236 /** 237 * @ todo might want to add rerequests to front of pending list for 238 * performance. 239 */ 240 mshr->readyIter = pendingList.insert(pendingList.end(), mshr); 241} 242 243void 244MSHRQueue::squash(int threadNum) 245{ 246 MSHR::Iterator i = allocatedList.begin(); 247 MSHR::Iterator end = allocatedList.end(); 248 for (; i != end;) { 249 MSHR *mshr = *i; 250 if (mshr->threadNum == threadNum) { 251 while (mshr->hasTargets()) { 252 Packet * target = mshr->getTarget(); 253 mshr->popTarget(); 254 255 assert(0/*target->req->getThreadNum()*/ == threadNum); 256 target = NULL; 257 } 258 assert(!mshr->hasTargets()); 259 assert(mshr->ntargets==0); 260 if (!mshr->inService) { 261 i = deallocateOne(mshr); 262 } else { 263 //mshr->pkt->flags &= ~CACHE_LINE_FILL; 264 ++i; 265 } 266 } else { 267 ++i; 268 } 269 } 270} 271