mshr_queue.cc revision 5314
12623SN/A/*
28948Sandreas.hansson@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
37725SAli.Saidi@ARM.com * All rights reserved.
47725SAli.Saidi@ARM.com *
57725SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without
67725SAli.Saidi@ARM.com * modification, are permitted provided that the following conditions are
77725SAli.Saidi@ARM.com * met: redistributions of source code must retain the above copyright
87725SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer;
97725SAli.Saidi@ARM.com * redistributions in binary form must reproduce the above copyright
107725SAli.Saidi@ARM.com * notice, this list of conditions and the following disclaimer in the
117725SAli.Saidi@ARM.com * documentation and/or other materials provided with the distribution;
127725SAli.Saidi@ARM.com * neither the name of the copyright holders nor the names of its
137725SAli.Saidi@ARM.com * 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.
272623SN/A *
282623SN/A * Authors: Erik Hallnor
292623SN/A */
302623SN/A
312623SN/A/** @file
322623SN/A * Definition of MSHRQueue class functions.
332623SN/A */
342623SN/A
352623SN/A#include "mem/cache/miss/mshr_queue.hh"
362623SN/A
372623SN/Ausing namespace std;
382623SN/A
392665Ssaidi@eecs.umich.eduMSHRQueue::MSHRQueue(const std::string &_label,
402665Ssaidi@eecs.umich.edu                     int num_entries, int reserve, int _index)
412623SN/A    : label(_label),
422623SN/A      numEntries(num_entries + reserve - 1), numReserve(reserve),
433170Sstever@eecs.umich.edu      index(_index)
448105Sgblack@eecs.umich.edu{
452623SN/A    allocated = 0;
464040Ssaidi@eecs.umich.edu    inServiceEntries = 0;
476658Snate@binkert.org    registers = new MSHR[numEntries];
488229Snate@binkert.org    for (int i = 0; i < numEntries; ++i) {
492623SN/A        registers[i].queue = this;
508232Snate@binkert.org        freeList.push_back(&registers[i]);
519152Satgutier@umich.edu    }
528232Snate@binkert.org}
538232Snate@binkert.org
543348Sbinkertn@umich.eduMSHRQueue::~MSHRQueue()
553348Sbinkertn@umich.edu{
564762Snate@binkert.org    delete [] registers;
577678Sgblack@eecs.umich.edu}
588779Sgblack@eecs.umich.edu
592901Ssaidi@eecs.umich.eduMSHR *
602623SN/AMSHRQueue::findMatch(Addr addr) const
612623SN/A{
622623SN/A    MSHR::ConstIterator i = allocatedList.begin();
632623SN/A    MSHR::ConstIterator end = allocatedList.end();
642623SN/A    for (; i != end; ++i) {
652623SN/A        MSHR *mshr = *i;
662623SN/A        if (mshr->addr == addr) {
672623SN/A            return mshr;
688921Sandreas.hansson@arm.com        }
698921Sandreas.hansson@arm.com    }
708921Sandreas.hansson@arm.com    return NULL;
718921Sandreas.hansson@arm.com}
729433SAndreas.Sandberg@ARM.com
738779Sgblack@eecs.umich.edubool
748779Sgblack@eecs.umich.eduMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
758779Sgblack@eecs.umich.edu{
768779Sgblack@eecs.umich.edu    // Need an empty vector
778779Sgblack@eecs.umich.edu    assert(matches.empty());
782623SN/A    bool retval = false;
792623SN/A    MSHR::ConstIterator i = allocatedList.begin();
802623SN/A    MSHR::ConstIterator end = allocatedList.end();
812623SN/A    for (; i != end; ++i) {
828707Sandreas.hansson@arm.com        MSHR *mshr = *i;
832948Ssaidi@eecs.umich.edu        if (mshr->addr == addr) {
842948Ssaidi@eecs.umich.edu            retval = true;
855606Snate@binkert.org            matches.push_back(mshr);
862948Ssaidi@eecs.umich.edu        }
872948Ssaidi@eecs.umich.edu    }
885529Snate@binkert.org    return retval;
898707Sandreas.hansson@arm.com}
909179Sandreas.hansson@arm.com
919442SAndreas.Sandberg@ARM.com
922623SN/Abool
932623SN/AMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
943647Srdreslin@umich.edu{
957897Shestness@cs.utexas.edu    pkt->pushLabel(label);
962623SN/A    MSHR::ConstIterator i = allocatedList.begin();
972623SN/A    MSHR::ConstIterator end = allocatedList.end();
982623SN/A    for (; i != end; ++i) {
992623SN/A        MSHR *mshr = *i;
1002623SN/A        if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) {
1012623SN/A            pkt->popLabel();
1022623SN/A            return true;
1032901Ssaidi@eecs.umich.edu        }
1049342SAndreas.Sandberg@arm.com    }
1052798Sktlim@umich.edu    pkt->popLabel();
1069448SAndreas.Sandberg@ARM.com    return false;
1079448SAndreas.Sandberg@ARM.com}
1089448SAndreas.Sandberg@ARM.com
1099448SAndreas.Sandberg@ARM.com
1109342SAndreas.Sandberg@arm.comMSHR *
1119448SAndreas.Sandberg@ARM.comMSHRQueue::findPending(Addr addr, int size) const
1129442SAndreas.Sandberg@ARM.com{
1132901Ssaidi@eecs.umich.edu    MSHR::ConstIterator i = readyList.begin();
1142798Sktlim@umich.edu    MSHR::ConstIterator end = readyList.end();
1159342SAndreas.Sandberg@arm.com    for (; i != end; ++i) {
1169442SAndreas.Sandberg@ARM.com        MSHR *mshr = *i;
1179442SAndreas.Sandberg@ARM.com        if (mshr->addr < addr) {
1189442SAndreas.Sandberg@ARM.com            if (mshr->addr + mshr->size > addr) {
1199442SAndreas.Sandberg@ARM.com                return mshr;
1209442SAndreas.Sandberg@ARM.com            }
1219448SAndreas.Sandberg@ARM.com        } else {
1229648Sdam.sunwoo@arm.com            if (addr + size > mshr->addr) {
1239442SAndreas.Sandberg@ARM.com                return mshr;
1242901Ssaidi@eecs.umich.edu            }
1252798Sktlim@umich.edu        }
1262623SN/A    }
1272623SN/A    return NULL;
1282623SN/A}
1299342SAndreas.Sandberg@arm.com
1302623SN/A
1319442SAndreas.Sandberg@ARM.comMSHR::Iterator
1329448SAndreas.Sandberg@ARM.comMSHRQueue::addToReadyList(MSHR *mshr)
1339448SAndreas.Sandberg@ARM.com{
1349448SAndreas.Sandberg@ARM.com    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
1359442SAndreas.Sandberg@ARM.com        return readyList.insert(readyList.end(), mshr);
1365221Ssaidi@eecs.umich.edu    }
1379523SAndreas.Sandberg@ARM.com
1383201Shsul@eecs.umich.edu    MSHR::Iterator i = readyList.begin();
1399448SAndreas.Sandberg@ARM.com    MSHR::Iterator end = readyList.end();
1409448SAndreas.Sandberg@ARM.com    for (; i != end; ++i) {
1419448SAndreas.Sandberg@ARM.com        if ((*i)->readyTime > mshr->readyTime) {
1429448SAndreas.Sandberg@ARM.com            return readyList.insert(i, mshr);
1439448SAndreas.Sandberg@ARM.com        }
1445710Scws3k@cs.virginia.edu    }
1459448SAndreas.Sandberg@ARM.com    assert(false);
1469837Slena@cs.wisc,edu    return end;  // keep stupid compilers happy
1479448SAndreas.Sandberg@ARM.com}
1489448SAndreas.Sandberg@ARM.com
1499837Slena@cs.wisc,edu
1502623SN/AMSHR *
1519442SAndreas.Sandberg@ARM.comMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
1522798Sktlim@umich.edu                    Tick when, Counter order)
1539442SAndreas.Sandberg@ARM.com{
1549442SAndreas.Sandberg@ARM.com    assert(!freeList.empty());
1559442SAndreas.Sandberg@ARM.com    MSHR *mshr = freeList.front();
1569442SAndreas.Sandberg@ARM.com    assert(mshr->getNumTargets() == 0);
1579442SAndreas.Sandberg@ARM.com    freeList.pop_front();
1589442SAndreas.Sandberg@ARM.com
1599442SAndreas.Sandberg@ARM.com    mshr->allocate(addr, size, pkt, when, order);
1609442SAndreas.Sandberg@ARM.com    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
1619442SAndreas.Sandberg@ARM.com    mshr->readyIter = addToReadyList(mshr);
1629442SAndreas.Sandberg@ARM.com
1639442SAndreas.Sandberg@ARM.com    allocated += 1;
1649442SAndreas.Sandberg@ARM.com    return mshr;
1659442SAndreas.Sandberg@ARM.com}
1669442SAndreas.Sandberg@ARM.com
1679442SAndreas.Sandberg@ARM.com
1682798Sktlim@umich.eduvoid
1692798Sktlim@umich.eduMSHRQueue::deallocate(MSHR *mshr)
1702798Sktlim@umich.edu{
1712798Sktlim@umich.edu    deallocateOne(mshr);
1722798Sktlim@umich.edu}
1739429SAndreas.Sandberg@ARM.com
1749429SAndreas.Sandberg@ARM.comMSHR::Iterator
1759442SAndreas.Sandberg@ARM.comMSHRQueue::deallocateOne(MSHR *mshr)
1769342SAndreas.Sandberg@arm.com{
1779442SAndreas.Sandberg@ARM.com    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
1789442SAndreas.Sandberg@ARM.com    freeList.push_front(mshr);
1799442SAndreas.Sandberg@ARM.com    allocated--;
1809179Sandreas.hansson@arm.com    if (mshr->inService) {
1812623SN/A        inServiceEntries--;
1822623SN/A    } else {
1832623SN/A        readyList.erase(mshr->readyIter);
1842623SN/A    }
1852623SN/A    mshr->deallocate();
1862623SN/A    return retval;
1879429SAndreas.Sandberg@ARM.com}
1882623SN/A
1899179Sandreas.hansson@arm.comvoid
1902623SN/AMSHRQueue::moveToFront(MSHR *mshr)
1912623SN/A{
1929523SAndreas.Sandberg@ARM.com    if (!mshr->inService) {
1939523SAndreas.Sandberg@ARM.com        assert(mshr == *(mshr->readyIter));
1949523SAndreas.Sandberg@ARM.com        readyList.erase(mshr->readyIter);
1959524SAndreas.Sandberg@ARM.com        mshr->readyIter = readyList.insert(readyList.begin(), mshr);
1969523SAndreas.Sandberg@ARM.com    }
1979523SAndreas.Sandberg@ARM.com}
1989523SAndreas.Sandberg@ARM.com
1999523SAndreas.Sandberg@ARM.comvoid
2002623SN/AMSHRQueue::markInService(MSHR *mshr)
2012623SN/A{
2029180Sandreas.hansson@arm.com    if (mshr->markInService()) {
2032623SN/A        deallocate(mshr);
2045221Ssaidi@eecs.umich.edu    } else {
2055221Ssaidi@eecs.umich.edu        readyList.erase(mshr->readyIter);
2062623SN/A        inServiceEntries += 1;
2072683Sktlim@umich.edu    }
2082623SN/A}
2092623SN/A
2102623SN/Avoid
2119837Slena@cs.wisc,eduMSHRQueue::markPending(MSHR *mshr)
2129342SAndreas.Sandberg@arm.com{
2133686Sktlim@umich.edu    assert(mshr->inService);
2142623SN/A    mshr->inService = false;
2159179Sandreas.hansson@arm.com    --inServiceEntries;
2162623SN/A    /**
2172623SN/A     * @ todo might want to add rerequests to front of pending list for
2182623SN/A     * performance.
2192623SN/A     */
2208737Skoansin.tan@gmail.com    mshr->readyIter = addToReadyList(mshr);
2212623SN/A}
2225221Ssaidi@eecs.umich.edu
2235221Ssaidi@eecs.umich.eduvoid
2242623SN/AMSHRQueue::squash(int threadNum)
2252683Sktlim@umich.edu{
2262623SN/A    MSHR::Iterator i = allocatedList.begin();
2276043Sgblack@eecs.umich.edu    MSHR::Iterator end = allocatedList.end();
2286043Sgblack@eecs.umich.edu    for (; i != end;) {
2296043Sgblack@eecs.umich.edu        MSHR *mshr = *i;
2309342SAndreas.Sandberg@arm.com        if (mshr->threadNum == threadNum) {
2312623SN/A            while (mshr->hasTargets()) {
2322644Sstever@eecs.umich.edu                mshr->popTarget();
2332644Sstever@eecs.umich.edu                assert(0/*target->req->getThreadNum()*/ == threadNum);
2342623SN/A            }
2359837Slena@cs.wisc,edu            assert(!mshr->hasTargets());
2362623SN/A            assert(mshr->ntargets==0);
2372623SN/A            if (!mshr->inService) {
2382623SN/A                i = deallocateOne(mshr);
2395728Sgblack@eecs.umich.edu            } else {
2405728Sgblack@eecs.umich.edu                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
2415728Sgblack@eecs.umich.edu                ++i;
2425728Sgblack@eecs.umich.edu            }
2438105Sgblack@eecs.umich.edu        } else {
2449180Sandreas.hansson@arm.com            ++i;
2459179Sandreas.hansson@arm.com        }
2465728Sgblack@eecs.umich.edu    }
2475728Sgblack@eecs.umich.edu}
2488975Sandreas.hansson@arm.com