mshr_queue.cc revision 5314
110259SAndrew.Bardsley@arm.com/* 210259SAndrew.Bardsley@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan 310259SAndrew.Bardsley@arm.com * All rights reserved. 410259SAndrew.Bardsley@arm.com * 510259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without 610259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are 710259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright 810259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer; 910259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright 1010259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the 1110259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution; 1210259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its 1310259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from 1410259SAndrew.Bardsley@arm.com * this software without specific prior written permission. 1510259SAndrew.Bardsley@arm.com * 1610259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710259SAndrew.Bardsley@arm.com * 2810259SAndrew.Bardsley@arm.com * Authors: Erik Hallnor 2910259SAndrew.Bardsley@arm.com */ 3010259SAndrew.Bardsley@arm.com 3110259SAndrew.Bardsley@arm.com/** @file 3210259SAndrew.Bardsley@arm.com * Definition of MSHRQueue class functions. 3310259SAndrew.Bardsley@arm.com */ 3410259SAndrew.Bardsley@arm.com 3510259SAndrew.Bardsley@arm.com#include "mem/cache/miss/mshr_queue.hh" 3610259SAndrew.Bardsley@arm.com 3710259SAndrew.Bardsley@arm.comusing namespace std; 3810259SAndrew.Bardsley@arm.com 3910259SAndrew.Bardsley@arm.comMSHRQueue::MSHRQueue(const std::string &_label, 4010259SAndrew.Bardsley@arm.com int num_entries, int reserve, int _index) 4110259SAndrew.Bardsley@arm.com : label(_label), 4210259SAndrew.Bardsley@arm.com numEntries(num_entries + reserve - 1), numReserve(reserve), 4310259SAndrew.Bardsley@arm.com index(_index) 4410259SAndrew.Bardsley@arm.com{ 4510259SAndrew.Bardsley@arm.com allocated = 0; 4610259SAndrew.Bardsley@arm.com inServiceEntries = 0; 4710259SAndrew.Bardsley@arm.com registers = new MSHR[numEntries]; 4810259SAndrew.Bardsley@arm.com for (int i = 0; i < numEntries; ++i) { 4910259SAndrew.Bardsley@arm.com registers[i].queue = this; 5010259SAndrew.Bardsley@arm.com freeList.push_back(®isters[i]); 5110259SAndrew.Bardsley@arm.com } 5210259SAndrew.Bardsley@arm.com} 5310259SAndrew.Bardsley@arm.com 5410259SAndrew.Bardsley@arm.comMSHRQueue::~MSHRQueue() 5510259SAndrew.Bardsley@arm.com{ 5610259SAndrew.Bardsley@arm.com delete [] registers; 5710259SAndrew.Bardsley@arm.com} 5810259SAndrew.Bardsley@arm.com 5910259SAndrew.Bardsley@arm.comMSHR * 6010259SAndrew.Bardsley@arm.comMSHRQueue::findMatch(Addr addr) const 6110259SAndrew.Bardsley@arm.com{ 6210259SAndrew.Bardsley@arm.com MSHR::ConstIterator i = allocatedList.begin(); 6310259SAndrew.Bardsley@arm.com MSHR::ConstIterator end = allocatedList.end(); 6410259SAndrew.Bardsley@arm.com for (; i != end; ++i) { 6510259SAndrew.Bardsley@arm.com MSHR *mshr = *i; 6610259SAndrew.Bardsley@arm.com if (mshr->addr == addr) { 6710259SAndrew.Bardsley@arm.com return mshr; 6810259SAndrew.Bardsley@arm.com } 6910259SAndrew.Bardsley@arm.com } 7010259SAndrew.Bardsley@arm.com return NULL; 7110259SAndrew.Bardsley@arm.com} 7210259SAndrew.Bardsley@arm.com 7310259SAndrew.Bardsley@arm.combool 7410259SAndrew.Bardsley@arm.comMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const 7510259SAndrew.Bardsley@arm.com{ 7610259SAndrew.Bardsley@arm.com // Need an empty vector 7710259SAndrew.Bardsley@arm.com assert(matches.empty()); 7810259SAndrew.Bardsley@arm.com bool retval = false; 7910259SAndrew.Bardsley@arm.com MSHR::ConstIterator i = allocatedList.begin(); 8010259SAndrew.Bardsley@arm.com MSHR::ConstIterator end = allocatedList.end(); 8110259SAndrew.Bardsley@arm.com for (; i != end; ++i) { 8210259SAndrew.Bardsley@arm.com MSHR *mshr = *i; 8310259SAndrew.Bardsley@arm.com if (mshr->addr == addr) { 8410259SAndrew.Bardsley@arm.com retval = true; 8510259SAndrew.Bardsley@arm.com matches.push_back(mshr); 8610259SAndrew.Bardsley@arm.com } 8710259SAndrew.Bardsley@arm.com } 8810259SAndrew.Bardsley@arm.com return retval; 8910259SAndrew.Bardsley@arm.com} 9010259SAndrew.Bardsley@arm.com 9110259SAndrew.Bardsley@arm.com 9210259SAndrew.Bardsley@arm.combool 9310259SAndrew.Bardsley@arm.comMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr) 9410259SAndrew.Bardsley@arm.com{ 9510259SAndrew.Bardsley@arm.com pkt->pushLabel(label); 9610259SAndrew.Bardsley@arm.com MSHR::ConstIterator i = allocatedList.begin(); 9710259SAndrew.Bardsley@arm.com MSHR::ConstIterator end = allocatedList.end(); 9810259SAndrew.Bardsley@arm.com for (; i != end; ++i) { 9910259SAndrew.Bardsley@arm.com MSHR *mshr = *i; 10010259SAndrew.Bardsley@arm.com if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) { 10110259SAndrew.Bardsley@arm.com pkt->popLabel(); 10210259SAndrew.Bardsley@arm.com return true; 10310259SAndrew.Bardsley@arm.com } 10410259SAndrew.Bardsley@arm.com } 10510259SAndrew.Bardsley@arm.com pkt->popLabel(); 10610259SAndrew.Bardsley@arm.com return false; 10710259SAndrew.Bardsley@arm.com} 10810259SAndrew.Bardsley@arm.com 10910259SAndrew.Bardsley@arm.com 11010259SAndrew.Bardsley@arm.comMSHR * 11110259SAndrew.Bardsley@arm.comMSHRQueue::findPending(Addr addr, int size) const 11210259SAndrew.Bardsley@arm.com{ 11310259SAndrew.Bardsley@arm.com MSHR::ConstIterator i = readyList.begin(); 11410259SAndrew.Bardsley@arm.com MSHR::ConstIterator end = readyList.end(); 11510259SAndrew.Bardsley@arm.com for (; i != end; ++i) { 11610259SAndrew.Bardsley@arm.com MSHR *mshr = *i; 11710259SAndrew.Bardsley@arm.com if (mshr->addr < addr) { 11810259SAndrew.Bardsley@arm.com if (mshr->addr + mshr->size > addr) { 11910259SAndrew.Bardsley@arm.com return mshr; 12010259SAndrew.Bardsley@arm.com } 12110259SAndrew.Bardsley@arm.com } else { 12210259SAndrew.Bardsley@arm.com if (addr + size > mshr->addr) { 12310259SAndrew.Bardsley@arm.com return mshr; 12410259SAndrew.Bardsley@arm.com } 12510259SAndrew.Bardsley@arm.com } 12610259SAndrew.Bardsley@arm.com } 12710259SAndrew.Bardsley@arm.com return NULL; 12810259SAndrew.Bardsley@arm.com} 12910259SAndrew.Bardsley@arm.com 13010259SAndrew.Bardsley@arm.com 13110259SAndrew.Bardsley@arm.comMSHR::Iterator 13210259SAndrew.Bardsley@arm.comMSHRQueue::addToReadyList(MSHR *mshr) 13310259SAndrew.Bardsley@arm.com{ 13410259SAndrew.Bardsley@arm.com if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) { 13510259SAndrew.Bardsley@arm.com return readyList.insert(readyList.end(), mshr); 13610259SAndrew.Bardsley@arm.com } 13710259SAndrew.Bardsley@arm.com 13810259SAndrew.Bardsley@arm.com MSHR::Iterator i = readyList.begin(); 13910259SAndrew.Bardsley@arm.com MSHR::Iterator end = readyList.end(); 14010259SAndrew.Bardsley@arm.com for (; i != end; ++i) { 14110259SAndrew.Bardsley@arm.com if ((*i)->readyTime > mshr->readyTime) { 14210259SAndrew.Bardsley@arm.com return readyList.insert(i, mshr); 14310259SAndrew.Bardsley@arm.com } 14410259SAndrew.Bardsley@arm.com } 14510259SAndrew.Bardsley@arm.com assert(false); 14610259SAndrew.Bardsley@arm.com return end; // keep stupid compilers happy 14710259SAndrew.Bardsley@arm.com} 14810259SAndrew.Bardsley@arm.com 14910259SAndrew.Bardsley@arm.com 15010259SAndrew.Bardsley@arm.comMSHR * 15110259SAndrew.Bardsley@arm.comMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt, 15210259SAndrew.Bardsley@arm.com Tick when, Counter order) 15310259SAndrew.Bardsley@arm.com{ 15410259SAndrew.Bardsley@arm.com assert(!freeList.empty()); 15510259SAndrew.Bardsley@arm.com MSHR *mshr = freeList.front(); 15610259SAndrew.Bardsley@arm.com assert(mshr->getNumTargets() == 0); 15710259SAndrew.Bardsley@arm.com freeList.pop_front(); 15810259SAndrew.Bardsley@arm.com 15910259SAndrew.Bardsley@arm.com mshr->allocate(addr, size, pkt, when, order); 16010259SAndrew.Bardsley@arm.com mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr); 16110259SAndrew.Bardsley@arm.com mshr->readyIter = addToReadyList(mshr); 16210259SAndrew.Bardsley@arm.com 16310259SAndrew.Bardsley@arm.com allocated += 1; 16410259SAndrew.Bardsley@arm.com return mshr; 16510259SAndrew.Bardsley@arm.com} 16610259SAndrew.Bardsley@arm.com 16710259SAndrew.Bardsley@arm.com 16810259SAndrew.Bardsley@arm.comvoid 16910259SAndrew.Bardsley@arm.comMSHRQueue::deallocate(MSHR *mshr) 17010259SAndrew.Bardsley@arm.com{ 17110259SAndrew.Bardsley@arm.com deallocateOne(mshr); 17210259SAndrew.Bardsley@arm.com} 17310259SAndrew.Bardsley@arm.com 17410259SAndrew.Bardsley@arm.comMSHR::Iterator 17510259SAndrew.Bardsley@arm.comMSHRQueue::deallocateOne(MSHR *mshr) 17610259SAndrew.Bardsley@arm.com{ 17710259SAndrew.Bardsley@arm.com MSHR::Iterator retval = allocatedList.erase(mshr->allocIter); 17810259SAndrew.Bardsley@arm.com freeList.push_front(mshr); 17910259SAndrew.Bardsley@arm.com allocated--; 18010259SAndrew.Bardsley@arm.com if (mshr->inService) { 18110259SAndrew.Bardsley@arm.com inServiceEntries--; 18210259SAndrew.Bardsley@arm.com } else { 18310259SAndrew.Bardsley@arm.com readyList.erase(mshr->readyIter); 18410259SAndrew.Bardsley@arm.com } 18510259SAndrew.Bardsley@arm.com mshr->deallocate(); 18610259SAndrew.Bardsley@arm.com return retval; 18710259SAndrew.Bardsley@arm.com} 18810259SAndrew.Bardsley@arm.com 18910259SAndrew.Bardsley@arm.comvoid 19010259SAndrew.Bardsley@arm.comMSHRQueue::moveToFront(MSHR *mshr) 19110259SAndrew.Bardsley@arm.com{ 19210259SAndrew.Bardsley@arm.com if (!mshr->inService) { 19310259SAndrew.Bardsley@arm.com assert(mshr == *(mshr->readyIter)); 19410259SAndrew.Bardsley@arm.com readyList.erase(mshr->readyIter); 19510259SAndrew.Bardsley@arm.com mshr->readyIter = readyList.insert(readyList.begin(), mshr); 19610259SAndrew.Bardsley@arm.com } 19710259SAndrew.Bardsley@arm.com} 19810259SAndrew.Bardsley@arm.com 19910259SAndrew.Bardsley@arm.comvoid 20010259SAndrew.Bardsley@arm.comMSHRQueue::markInService(MSHR *mshr) 20110259SAndrew.Bardsley@arm.com{ 20210259SAndrew.Bardsley@arm.com if (mshr->markInService()) { 20310259SAndrew.Bardsley@arm.com deallocate(mshr); 20410259SAndrew.Bardsley@arm.com } else { 20510259SAndrew.Bardsley@arm.com readyList.erase(mshr->readyIter); 20610259SAndrew.Bardsley@arm.com inServiceEntries += 1; 20710259SAndrew.Bardsley@arm.com } 20810259SAndrew.Bardsley@arm.com} 20910259SAndrew.Bardsley@arm.com 21010259SAndrew.Bardsley@arm.comvoid 21110259SAndrew.Bardsley@arm.comMSHRQueue::markPending(MSHR *mshr) 21210259SAndrew.Bardsley@arm.com{ 21310259SAndrew.Bardsley@arm.com assert(mshr->inService); 21410259SAndrew.Bardsley@arm.com mshr->inService = false; 21510259SAndrew.Bardsley@arm.com --inServiceEntries; 21610259SAndrew.Bardsley@arm.com /** 21710259SAndrew.Bardsley@arm.com * @ todo might want to add rerequests to front of pending list for 21810259SAndrew.Bardsley@arm.com * performance. 21910259SAndrew.Bardsley@arm.com */ 22010259SAndrew.Bardsley@arm.com mshr->readyIter = addToReadyList(mshr); 22110259SAndrew.Bardsley@arm.com} 22210259SAndrew.Bardsley@arm.com 22310259SAndrew.Bardsley@arm.comvoid 22410259SAndrew.Bardsley@arm.comMSHRQueue::squash(int threadNum) 22510259SAndrew.Bardsley@arm.com{ 22611567Smitch.hayenga@arm.com MSHR::Iterator i = allocatedList.begin(); 22711567Smitch.hayenga@arm.com MSHR::Iterator end = allocatedList.end(); 22810259SAndrew.Bardsley@arm.com for (; i != end;) { 22910259SAndrew.Bardsley@arm.com MSHR *mshr = *i; 23010259SAndrew.Bardsley@arm.com if (mshr->threadNum == threadNum) { 23110259SAndrew.Bardsley@arm.com while (mshr->hasTargets()) { 23210259SAndrew.Bardsley@arm.com mshr->popTarget(); 23310259SAndrew.Bardsley@arm.com assert(0/*target->req->getThreadNum()*/ == threadNum); 23410259SAndrew.Bardsley@arm.com } 23510259SAndrew.Bardsley@arm.com assert(!mshr->hasTargets()); 23610259SAndrew.Bardsley@arm.com assert(mshr->ntargets==0); 23710259SAndrew.Bardsley@arm.com if (!mshr->inService) { 23810259SAndrew.Bardsley@arm.com i = deallocateOne(mshr); 23910259SAndrew.Bardsley@arm.com } else { 24010259SAndrew.Bardsley@arm.com //mshr->pkt->flags &= ~CACHE_LINE_FILL; 24110259SAndrew.Bardsley@arm.com ++i; 24210259SAndrew.Bardsley@arm.com } 24310259SAndrew.Bardsley@arm.com } else { 24410259SAndrew.Bardsley@arm.com ++i; 24510259SAndrew.Bardsley@arm.com } 24610259SAndrew.Bardsley@arm.com } 24710259SAndrew.Bardsley@arm.com} 24810259SAndrew.Bardsley@arm.com