mshr_queue.cc revision 5314
12810Srdreslin@umich.edu/* 211051Sandreas.hansson@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 311051Sandreas.hansson@arm.com * All rights reserved. 411051Sandreas.hansson@arm.com * 511051Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without 611051Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are 711051Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright 811051Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer; 911051Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright 1011051Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the 1111051Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution; 1211051Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its 1311051Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from 1411051Sandreas.hansson@arm.com * this software without specific prior written permission. 1511051Sandreas.hansson@arm.com * 162810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272810Srdreslin@umich.edu * 282810Srdreslin@umich.edu * Authors: Erik Hallnor 292810Srdreslin@umich.edu */ 302810Srdreslin@umich.edu 312810Srdreslin@umich.edu/** @file 322810Srdreslin@umich.edu * Definition of MSHRQueue class functions. 332810Srdreslin@umich.edu */ 342810Srdreslin@umich.edu 352810Srdreslin@umich.edu#include "mem/cache/miss/mshr_queue.hh" 362810Srdreslin@umich.edu 372810Srdreslin@umich.eduusing namespace std; 382810Srdreslin@umich.edu 392810Srdreslin@umich.eduMSHRQueue::MSHRQueue(const std::string &_label, 402810Srdreslin@umich.edu int num_entries, int reserve, int _index) 412810Srdreslin@umich.edu : label(_label), 4211051Sandreas.hansson@arm.com numEntries(num_entries + reserve - 1), numReserve(reserve), 4311051Sandreas.hansson@arm.com index(_index) 442810Srdreslin@umich.edu{ 4511051Sandreas.hansson@arm.com allocated = 0; 4611051Sandreas.hansson@arm.com inServiceEntries = 0; 472810Srdreslin@umich.edu registers = new MSHR[numEntries]; 482810Srdreslin@umich.edu for (int i = 0; i < numEntries; ++i) { 492810Srdreslin@umich.edu registers[i].queue = this; 502810Srdreslin@umich.edu freeList.push_back(®isters[i]); 5111051Sandreas.hansson@arm.com } 522810Srdreslin@umich.edu} 532810Srdreslin@umich.edu 5411051Sandreas.hansson@arm.comMSHRQueue::~MSHRQueue() 552810Srdreslin@umich.edu{ 5611051Sandreas.hansson@arm.com delete [] registers; 5711051Sandreas.hansson@arm.com} 5811051Sandreas.hansson@arm.com 5911051Sandreas.hansson@arm.comMSHR * 6011051Sandreas.hansson@arm.comMSHRQueue::findMatch(Addr addr) const 6111051Sandreas.hansson@arm.com{ 6211051Sandreas.hansson@arm.com MSHR::ConstIterator i = allocatedList.begin(); 6311051Sandreas.hansson@arm.com MSHR::ConstIterator end = allocatedList.end(); 6411051Sandreas.hansson@arm.com for (; i != end; ++i) { 6511051Sandreas.hansson@arm.com MSHR *mshr = *i; 6611053Sandreas.hansson@arm.com if (mshr->addr == addr) { 6711053Sandreas.hansson@arm.com return mshr; 6811051Sandreas.hansson@arm.com } 6911051Sandreas.hansson@arm.com } 7011051Sandreas.hansson@arm.com return NULL; 7111197Sandreas.hansson@arm.com} 7211197Sandreas.hansson@arm.com 7311199Sandreas.hansson@arm.combool 7411197Sandreas.hansson@arm.comMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const 7511197Sandreas.hansson@arm.com{ 7611197Sandreas.hansson@arm.com // Need an empty vector 7711051Sandreas.hansson@arm.com assert(matches.empty()); 7811051Sandreas.hansson@arm.com bool retval = false; 7911051Sandreas.hansson@arm.com MSHR::ConstIterator i = allocatedList.begin(); 8011051Sandreas.hansson@arm.com MSHR::ConstIterator end = allocatedList.end(); 8111051Sandreas.hansson@arm.com for (; i != end; ++i) { 8211051Sandreas.hansson@arm.com MSHR *mshr = *i; 8311051Sandreas.hansson@arm.com if (mshr->addr == addr) { 8411051Sandreas.hansson@arm.com retval = true; 8511051Sandreas.hansson@arm.com matches.push_back(mshr); 8611051Sandreas.hansson@arm.com } 8711051Sandreas.hansson@arm.com } 8811051Sandreas.hansson@arm.com return retval; 8911051Sandreas.hansson@arm.com} 9011051Sandreas.hansson@arm.com 9111051Sandreas.hansson@arm.com 9211051Sandreas.hansson@arm.combool 9311051Sandreas.hansson@arm.comMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr) 9411051Sandreas.hansson@arm.com{ 9511051Sandreas.hansson@arm.com pkt->pushLabel(label); 9611051Sandreas.hansson@arm.com MSHR::ConstIterator i = allocatedList.begin(); 9711051Sandreas.hansson@arm.com MSHR::ConstIterator end = allocatedList.end(); 9811051Sandreas.hansson@arm.com for (; i != end; ++i) { 9911051Sandreas.hansson@arm.com MSHR *mshr = *i; 10011051Sandreas.hansson@arm.com if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) { 10111051Sandreas.hansson@arm.com pkt->popLabel(); 10211051Sandreas.hansson@arm.com return true; 10311051Sandreas.hansson@arm.com } 10411051Sandreas.hansson@arm.com } 10511051Sandreas.hansson@arm.com pkt->popLabel(); 10611051Sandreas.hansson@arm.com return false; 10711051Sandreas.hansson@arm.com} 10811051Sandreas.hansson@arm.com 10911051Sandreas.hansson@arm.com 11011051Sandreas.hansson@arm.comMSHR * 11111051Sandreas.hansson@arm.comMSHRQueue::findPending(Addr addr, int size) const 11211051Sandreas.hansson@arm.com{ 11311051Sandreas.hansson@arm.com MSHR::ConstIterator i = readyList.begin(); 11411051Sandreas.hansson@arm.com MSHR::ConstIterator end = readyList.end(); 11511051Sandreas.hansson@arm.com for (; i != end; ++i) { 11611051Sandreas.hansson@arm.com MSHR *mshr = *i; 11711051Sandreas.hansson@arm.com if (mshr->addr < addr) { 11811051Sandreas.hansson@arm.com if (mshr->addr + mshr->size > addr) { 11911051Sandreas.hansson@arm.com return mshr; 12011051Sandreas.hansson@arm.com } 12111051Sandreas.hansson@arm.com } else { 12211051Sandreas.hansson@arm.com if (addr + size > mshr->addr) { 12311051Sandreas.hansson@arm.com return mshr; 12411051Sandreas.hansson@arm.com } 12511051Sandreas.hansson@arm.com } 12611051Sandreas.hansson@arm.com } 12711051Sandreas.hansson@arm.com return NULL; 12811051Sandreas.hansson@arm.com} 12911051Sandreas.hansson@arm.com 13011051Sandreas.hansson@arm.com 13111051Sandreas.hansson@arm.comMSHR::Iterator 13211051Sandreas.hansson@arm.comMSHRQueue::addToReadyList(MSHR *mshr) 13311051Sandreas.hansson@arm.com{ 13411051Sandreas.hansson@arm.com if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) { 13511051Sandreas.hansson@arm.com return readyList.insert(readyList.end(), mshr); 13611051Sandreas.hansson@arm.com } 13711051Sandreas.hansson@arm.com 13811051Sandreas.hansson@arm.com MSHR::Iterator i = readyList.begin(); 13911051Sandreas.hansson@arm.com MSHR::Iterator end = readyList.end(); 14011051Sandreas.hansson@arm.com for (; i != end; ++i) { 14111051Sandreas.hansson@arm.com if ((*i)->readyTime > mshr->readyTime) { 14211051Sandreas.hansson@arm.com return readyList.insert(i, mshr); 14311051Sandreas.hansson@arm.com } 14411051Sandreas.hansson@arm.com } 14511051Sandreas.hansson@arm.com assert(false); 14611051Sandreas.hansson@arm.com return end; // keep stupid compilers happy 14711051Sandreas.hansson@arm.com} 14811051Sandreas.hansson@arm.com 14911051Sandreas.hansson@arm.com 15011051Sandreas.hansson@arm.comMSHR * 15111051Sandreas.hansson@arm.comMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt, 15211051Sandreas.hansson@arm.com Tick when, Counter order) 15311051Sandreas.hansson@arm.com{ 15411051Sandreas.hansson@arm.com assert(!freeList.empty()); 15511051Sandreas.hansson@arm.com MSHR *mshr = freeList.front(); 15611051Sandreas.hansson@arm.com assert(mshr->getNumTargets() == 0); 15711051Sandreas.hansson@arm.com freeList.pop_front(); 15811051Sandreas.hansson@arm.com 15911051Sandreas.hansson@arm.com mshr->allocate(addr, size, pkt, when, order); 16011051Sandreas.hansson@arm.com mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 16111051Sandreas.hansson@arm.com mshr->readyIter = addToReadyList(mshr); 16211051Sandreas.hansson@arm.com 16311051Sandreas.hansson@arm.com allocated += 1; 16411051Sandreas.hansson@arm.com return mshr; 16511051Sandreas.hansson@arm.com} 16611051Sandreas.hansson@arm.com 16711051Sandreas.hansson@arm.com 16811051Sandreas.hansson@arm.comvoid 16911051Sandreas.hansson@arm.comMSHRQueue::deallocate(MSHR *mshr) 17011051Sandreas.hansson@arm.com{ 17111051Sandreas.hansson@arm.com deallocateOne(mshr); 17211051Sandreas.hansson@arm.com} 17311051Sandreas.hansson@arm.com 17411051Sandreas.hansson@arm.comMSHR::Iterator 17511051Sandreas.hansson@arm.comMSHRQueue::deallocateOne(MSHR *mshr) 17611051Sandreas.hansson@arm.com{ 17711051Sandreas.hansson@arm.com MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 17811051Sandreas.hansson@arm.com freeList.push_front(mshr); 17911051Sandreas.hansson@arm.com allocated--; 18011051Sandreas.hansson@arm.com if (mshr->inService) { 18111051Sandreas.hansson@arm.com inServiceEntries--; 18211051Sandreas.hansson@arm.com } else { 18311051Sandreas.hansson@arm.com readyList.erase(mshr->readyIter); 18411051Sandreas.hansson@arm.com } 18511051Sandreas.hansson@arm.com mshr->deallocate(); 18611051Sandreas.hansson@arm.com return retval; 18711051Sandreas.hansson@arm.com} 18811051Sandreas.hansson@arm.com 18911051Sandreas.hansson@arm.comvoid 19011051Sandreas.hansson@arm.comMSHRQueue::moveToFront(MSHR *mshr) 19111051Sandreas.hansson@arm.com{ 19211051Sandreas.hansson@arm.com if (!mshr->inService) { 19311051Sandreas.hansson@arm.com assert(mshr == *(mshr->readyIter)); 19411051Sandreas.hansson@arm.com readyList.erase(mshr->readyIter); 19511051Sandreas.hansson@arm.com mshr->readyIter = readyList.insert(readyList.begin(), mshr); 19611051Sandreas.hansson@arm.com } 19711051Sandreas.hansson@arm.com} 19811051Sandreas.hansson@arm.com 19911051Sandreas.hansson@arm.comvoid 20011051Sandreas.hansson@arm.comMSHRQueue::markInService(MSHR *mshr) 20111051Sandreas.hansson@arm.com{ 20211051Sandreas.hansson@arm.com if (mshr->markInService()) { 20311051Sandreas.hansson@arm.com deallocate(mshr); 20411051Sandreas.hansson@arm.com } else { 20511051Sandreas.hansson@arm.com readyList.erase(mshr->readyIter); 20611197Sandreas.hansson@arm.com inServiceEntries += 1; 20711197Sandreas.hansson@arm.com } 20811197Sandreas.hansson@arm.com} 20911197Sandreas.hansson@arm.com 21011051Sandreas.hansson@arm.comvoid 21111051Sandreas.hansson@arm.comMSHRQueue::markPending(MSHR *mshr) 21211051Sandreas.hansson@arm.com{ 21311051Sandreas.hansson@arm.com assert(mshr->inService); 21411051Sandreas.hansson@arm.com mshr->inService = false; 21511051Sandreas.hansson@arm.com --inServiceEntries; 21611051Sandreas.hansson@arm.com /** 21711051Sandreas.hansson@arm.com * @ todo might want to add rerequests to front of pending list for 21811051Sandreas.hansson@arm.com * performance. 21911051Sandreas.hansson@arm.com */ 22011051Sandreas.hansson@arm.com mshr->readyIter = addToReadyList(mshr); 22111051Sandreas.hansson@arm.com} 22211051Sandreas.hansson@arm.com 22311051Sandreas.hansson@arm.comvoid 22411051Sandreas.hansson@arm.comMSHRQueue::squash(int threadNum) 22511051Sandreas.hansson@arm.com{ 22611051Sandreas.hansson@arm.com MSHR::Iterator i = allocatedList.begin(); 22711051Sandreas.hansson@arm.com MSHR::Iterator end = allocatedList.end(); 22811197Sandreas.hansson@arm.com for (; i != end;) { 22911197Sandreas.hansson@arm.com MSHR *mshr = *i; 23011051Sandreas.hansson@arm.com if (mshr->threadNum == threadNum) { 23111197Sandreas.hansson@arm.com while (mshr->hasTargets()) { 23211197Sandreas.hansson@arm.com mshr->popTarget(); 23311197Sandreas.hansson@arm.com assert(0/*target->req->getThreadNum()*/ == threadNum); 23411197Sandreas.hansson@arm.com } 23511197Sandreas.hansson@arm.com assert(!mshr->hasTargets()); 23611197Sandreas.hansson@arm.com assert(mshr->ntargets==0); 23711197Sandreas.hansson@arm.com if (!mshr->inService) { 23811197Sandreas.hansson@arm.com i = deallocateOne(mshr); 23911197Sandreas.hansson@arm.com } else { 24011197Sandreas.hansson@arm.com //mshr->pkt->flags &= ~CACHE_LINE_FILL; 24111197Sandreas.hansson@arm.com ++i; 24211197Sandreas.hansson@arm.com } 24311197Sandreas.hansson@arm.com } else { 24411197Sandreas.hansson@arm.com ++i; 24511051Sandreas.hansson@arm.com } 24611197Sandreas.hansson@arm.com } 24711197Sandreas.hansson@arm.com} 24811197Sandreas.hansson@arm.com