mshr_queue.cc revision 5314
12623SN/A/*
22623SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32623SN/A * All rights reserved.
42623SN/A *
52623SN/A * Redistribution and use in source and binary forms, with or without
62623SN/A * modification, are permitted provided that the following conditions are
72623SN/A * met: redistributions of source code must retain the above copyright
82623SN/A * notice, this list of conditions and the following disclaimer;
92623SN/A * redistributions in binary form must reproduce the above copyright
102623SN/A * notice, this list of conditions and the following disclaimer in the
112623SN/A * documentation and/or other materials provided with the distribution;
122623SN/A * neither the name of the copyright holders nor the names of its
132623SN/A * 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.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Erik Hallnor
292623SN/A */
302623SN/A
313170Sstever@eecs.umich.edu/** @file
322623SN/A * Definition of MSHRQueue class functions.
334040Ssaidi@eecs.umich.edu */
342623SN/A
352623SN/A#include "mem/cache/miss/mshr_queue.hh"
363348Sbinkertn@umich.edu
373348Sbinkertn@umich.eduusing namespace std;
384762Snate@binkert.org
392901Ssaidi@eecs.umich.eduMSHRQueue::MSHRQueue(const std::string &_label,
402623SN/A                     int num_entries, int reserve, int _index)
412623SN/A    : label(_label),
422623SN/A      numEntries(num_entries + reserve - 1), numReserve(reserve),
432623SN/A      index(_index)
442856Srdreslin@umich.edu{
452856Srdreslin@umich.edu    allocated = 0;
462856Srdreslin@umich.edu    inServiceEntries = 0;
472856Srdreslin@umich.edu    registers = new MSHR[numEntries];
482856Srdreslin@umich.edu    for (int i = 0; i < numEntries; ++i) {
492856Srdreslin@umich.edu        registers[i].queue = this;
502856Srdreslin@umich.edu        freeList.push_back(&registers[i]);
512856Srdreslin@umich.edu    }
522856Srdreslin@umich.edu}
532856Srdreslin@umich.edu
542623SN/AMSHRQueue::~MSHRQueue()
552623SN/A{
562623SN/A    delete [] registers;
572623SN/A}
582623SN/A
592623SN/AMSHR *
602680Sktlim@umich.eduMSHRQueue::findMatch(Addr addr) const
612680Sktlim@umich.edu{
622623SN/A    MSHR::ConstIterator i = allocatedList.begin();
632623SN/A    MSHR::ConstIterator end = allocatedList.end();
642680Sktlim@umich.edu    for (; i != end; ++i) {
652623SN/A        MSHR *mshr = *i;
662623SN/A        if (mshr->addr == addr) {
672623SN/A            return mshr;
682623SN/A        }
692623SN/A    }
703349Sbinkertn@umich.edu    return NULL;
712623SN/A}
722623SN/A
732623SN/Abool
742623SN/AMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
752623SN/A{
762623SN/A    // Need an empty vector
773349Sbinkertn@umich.edu    assert(matches.empty());
782623SN/A    bool retval = false;
793184Srdreslin@umich.edu    MSHR::ConstIterator i = allocatedList.begin();
803184Srdreslin@umich.edu    MSHR::ConstIterator end = allocatedList.end();
812623SN/A    for (; i != end; ++i) {
822623SN/A        MSHR *mshr = *i;
832623SN/A        if (mshr->addr == addr) {
842623SN/A            retval = true;
852623SN/A            matches.push_back(mshr);
863647Srdreslin@umich.edu        }
873647Srdreslin@umich.edu    }
883647Srdreslin@umich.edu    return retval;
893647Srdreslin@umich.edu}
903647Srdreslin@umich.edu
912631SN/A
923647Srdreslin@umich.edubool
932631SN/AMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
942623SN/A{
952623SN/A    pkt->pushLabel(label);
962623SN/A    MSHR::ConstIterator i = allocatedList.begin();
972948Ssaidi@eecs.umich.edu    MSHR::ConstIterator end = allocatedList.end();
982948Ssaidi@eecs.umich.edu    for (; i != end; ++i) {
993349Sbinkertn@umich.edu        MSHR *mshr = *i;
1002948Ssaidi@eecs.umich.edu        if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) {
1012948Ssaidi@eecs.umich.edu            pkt->popLabel();
1022948Ssaidi@eecs.umich.edu            return true;
1032948Ssaidi@eecs.umich.edu        }
1042948Ssaidi@eecs.umich.edu    }
1052623SN/A    pkt->popLabel();
1063170Sstever@eecs.umich.edu    return false;
1073170Sstever@eecs.umich.edu}
1082623SN/A
1092623SN/A
1103647Srdreslin@umich.eduMSHR *
1113647Srdreslin@umich.eduMSHRQueue::findPending(Addr addr, int size) const
1123647Srdreslin@umich.edu{
1133647Srdreslin@umich.edu    MSHR::ConstIterator i = readyList.begin();
1142623SN/A    MSHR::ConstIterator end = readyList.end();
1152839Sktlim@umich.edu    for (; i != end; ++i) {
1162867Sktlim@umich.edu        MSHR *mshr = *i;
1173222Sktlim@umich.edu        if (mshr->addr < addr) {
1182901Ssaidi@eecs.umich.edu            if (mshr->addr + mshr->size > addr) {
1192623SN/A                return mshr;
1202623SN/A            }
1212623SN/A        } else {
1222623SN/A            if (addr + size > mshr->addr) {
1232623SN/A                return mshr;
1242623SN/A            }
1252623SN/A        }
1262623SN/A    }
1272623SN/A    return NULL;
1282623SN/A}
1292915Sktlim@umich.edu
1302915Sktlim@umich.edu
1312623SN/AMSHR::Iterator
1322623SN/AMSHRQueue::addToReadyList(MSHR *mshr)
1332623SN/A{
1342623SN/A    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
1352623SN/A        return readyList.insert(readyList.end(), mshr);
1362623SN/A    }
1372915Sktlim@umich.edu
1382915Sktlim@umich.edu    MSHR::Iterator i = readyList.begin();
1392623SN/A    MSHR::Iterator end = readyList.end();
1402798Sktlim@umich.edu    for (; i != end; ++i) {
1412798Sktlim@umich.edu        if ((*i)->readyTime > mshr->readyTime) {
1422901Ssaidi@eecs.umich.edu            return readyList.insert(i, mshr);
1432839Sktlim@umich.edu        }
1442798Sktlim@umich.edu    }
1452839Sktlim@umich.edu    assert(false);
1462798Sktlim@umich.edu    return end;  // keep stupid compilers happy
1472798Sktlim@umich.edu}
1482901Ssaidi@eecs.umich.edu
1492901Ssaidi@eecs.umich.edu
1502798Sktlim@umich.eduMSHR *
1512839Sktlim@umich.eduMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
1522839Sktlim@umich.edu                    Tick when, Counter order)
1532901Ssaidi@eecs.umich.edu{
1542798Sktlim@umich.edu    assert(!freeList.empty());
1552623SN/A    MSHR *mshr = freeList.front();
1562623SN/A    assert(mshr->getNumTargets() == 0);
1572623SN/A    freeList.pop_front();
1582798Sktlim@umich.edu
1592623SN/A    mshr->allocate(addr, size, pkt, when, order);
1602798Sktlim@umich.edu    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
1614762Snate@binkert.org    mshr->readyIter = addToReadyList(mshr);
1623201Shsul@eecs.umich.edu
1632867Sktlim@umich.edu    allocated += 1;
1642867Sktlim@umich.edu    return mshr;
1652915Sktlim@umich.edu}
1662915Sktlim@umich.edu
1672915Sktlim@umich.edu
1682867Sktlim@umich.eduvoid
1692867Sktlim@umich.eduMSHRQueue::deallocate(MSHR *mshr)
1702867Sktlim@umich.edu{
1714471Sstever@eecs.umich.edu    deallocateOne(mshr);
1722623SN/A}
1732798Sktlim@umich.edu
1742901Ssaidi@eecs.umich.eduMSHR::Iterator
1753222Sktlim@umich.eduMSHRQueue::deallocateOne(MSHR *mshr)
1762798Sktlim@umich.edu{
1772798Sktlim@umich.edu    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
1782798Sktlim@umich.edu    freeList.push_front(mshr);
1792798Sktlim@umich.edu    allocated--;
1802798Sktlim@umich.edu    if (mshr->inService) {
1812798Sktlim@umich.edu        inServiceEntries--;
1822798Sktlim@umich.edu    } else {
1833222Sktlim@umich.edu        readyList.erase(mshr->readyIter);
1842867Sktlim@umich.edu    }
1852867Sktlim@umich.edu    mshr->deallocate();
1862867Sktlim@umich.edu    return retval;
1872867Sktlim@umich.edu}
1882867Sktlim@umich.edu
1892623SN/Avoid
1902623SN/AMSHRQueue::moveToFront(MSHR *mshr)
1912623SN/A{
1922623SN/A    if (!mshr->inService) {
1932623SN/A        assert(mshr == *(mshr->readyIter));
1942623SN/A        readyList.erase(mshr->readyIter);
1954192Sktlim@umich.edu        mshr->readyIter = readyList.insert(readyList.begin(), mshr);
1962623SN/A    }
1972680Sktlim@umich.edu}
1982623SN/A
1992680Sktlim@umich.eduvoid
2002680Sktlim@umich.eduMSHRQueue::markInService(MSHR *mshr)
2012680Sktlim@umich.edu{
2022623SN/A    if (mshr->markInService()) {
2032623SN/A        deallocate(mshr);
2042623SN/A    } else {
2052623SN/A        readyList.erase(mshr->readyIter);
2063201Shsul@eecs.umich.edu        inServiceEntries += 1;
2073201Shsul@eecs.umich.edu    }
2083201Shsul@eecs.umich.edu}
2093201Shsul@eecs.umich.edu
2102623SN/Avoid
2112623SN/AMSHRQueue::markPending(MSHR *mshr)
2122623SN/A{
2132623SN/A    assert(mshr->inService);
2142623SN/A    mshr->inService = false;
2152623SN/A    --inServiceEntries;
2162623SN/A    /**
2172683Sktlim@umich.edu     * @ todo might want to add rerequests to front of pending list for
2182623SN/A     * performance.
2192623SN/A     */
2202623SN/A    mshr->readyIter = addToReadyList(mshr);
2212623SN/A}
2222623SN/A
2233686Sktlim@umich.eduvoid
2242623SN/AMSHRQueue::squash(int threadNum)
2254471Sstever@eecs.umich.edu{
2262623SN/A    MSHR::Iterator i = allocatedList.begin();
2272623SN/A    MSHR::Iterator end = allocatedList.end();
2282623SN/A    for (; i != end;) {
2292623SN/A        MSHR *mshr = *i;
2302623SN/A        if (mshr->threadNum == threadNum) {
2312623SN/A            while (mshr->hasTargets()) {
2322623SN/A                mshr->popTarget();
2332683Sktlim@umich.edu                assert(0/*target->req->getThreadNum()*/ == threadNum);
2342623SN/A            }
2352644Sstever@eecs.umich.edu            assert(!mshr->hasTargets());
2362623SN/A            assert(mshr->ntargets==0);
2372644Sstever@eecs.umich.edu            if (!mshr->inService) {
2382644Sstever@eecs.umich.edu                i = deallocateOne(mshr);
2392623SN/A            } else {
2402623SN/A                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
2412623SN/A                ++i;
2422623SN/A            }
2432623SN/A        } else {
2442623SN/A            ++i;
2452623SN/A        }
2462623SN/A    }
2472623SN/A}
2482623SN/A