mshr_queue.cc revision 5715
12810SN/A/*
22810SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32810SN/A * All rights reserved.
42810SN/A *
52810SN/A * Redistribution and use in source and binary forms, with or without
62810SN/A * modification, are permitted provided that the following conditions are
72810SN/A * met: redistributions of source code must retain the above copyright
82810SN/A * notice, this list of conditions and the following disclaimer;
92810SN/A * redistributions in binary form must reproduce the above copyright
102810SN/A * notice, this list of conditions and the following disclaimer in the
112810SN/A * documentation and/or other materials provided with the distribution;
122810SN/A * neither the name of the copyright holders nor the names of its
132810SN/A * contributors may be used to endorse or promote products derived from
142810SN/A * this software without specific prior written permission.
152810SN/A *
162810SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172810SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182810SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192810SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202810SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212810SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222810SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232810SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242810SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252810SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262810SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272810SN/A *
282810SN/A * Authors: Erik Hallnor
292810SN/A */
302810SN/A
312810SN/A/** @file
324626SN/A * Definition of MSHRQueue class functions.
332810SN/A */
342810SN/A
355338Sstever@gmail.com#include "mem/cache/mshr_queue.hh"
362810SN/A
372810SN/Ausing namespace std;
382810SN/A
395314SN/AMSHRQueue::MSHRQueue(const std::string &_label,
405314SN/A                     int num_entries, int reserve, int _index)
415314SN/A    : label(_label),
425314SN/A      numEntries(num_entries + reserve - 1), numReserve(reserve),
434628SN/A      index(_index)
442810SN/A{
452810SN/A    allocated = 0;
464626SN/A    inServiceEntries = 0;
474626SN/A    registers = new MSHR[numEntries];
484626SN/A    for (int i = 0; i < numEntries; ++i) {
494626SN/A        registers[i].queue = this;
502810SN/A        freeList.push_back(&registers[i]);
512810SN/A    }
522810SN/A}
532810SN/A
542810SN/AMSHRQueue::~MSHRQueue()
552810SN/A{
562810SN/A    delete [] registers;
572810SN/A}
582810SN/A
594626SN/AMSHR *
602991SN/AMSHRQueue::findMatch(Addr addr) const
612810SN/A{
622810SN/A    MSHR::ConstIterator i = allocatedList.begin();
632810SN/A    MSHR::ConstIterator end = allocatedList.end();
642810SN/A    for (; i != end; ++i) {
652810SN/A        MSHR *mshr = *i;
662810SN/A        if (mshr->addr == addr) {
672810SN/A            return mshr;
682810SN/A        }
692810SN/A    }
702810SN/A    return NULL;
712810SN/A}
722810SN/A
732810SN/Abool
742991SN/AMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
752810SN/A{
762810SN/A    // Need an empty vector
772810SN/A    assert(matches.empty());
782810SN/A    bool retval = false;
792810SN/A    MSHR::ConstIterator i = allocatedList.begin();
802810SN/A    MSHR::ConstIterator end = allocatedList.end();
812810SN/A    for (; i != end; ++i) {
822810SN/A        MSHR *mshr = *i;
832810SN/A        if (mshr->addr == addr) {
842810SN/A            retval = true;
852810SN/A            matches.push_back(mshr);
862810SN/A        }
872810SN/A    }
882810SN/A    return retval;
894920SN/A}
902810SN/A
914920SN/A
924920SN/Abool
934920SN/AMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
944920SN/A{
955314SN/A    pkt->pushLabel(label);
964920SN/A    MSHR::ConstIterator i = allocatedList.begin();
974920SN/A    MSHR::ConstIterator end = allocatedList.end();
984920SN/A    for (; i != end; ++i) {
994920SN/A        MSHR *mshr = *i;
1004920SN/A        if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) {
1015314SN/A            pkt->popLabel();
1024920SN/A            return true;
1034920SN/A        }
1044920SN/A    }
1055314SN/A    pkt->popLabel();
1064920SN/A    return false;
1072810SN/A}
1082810SN/A
1094920SN/A
1104626SN/AMSHR *
1114626SN/AMSHRQueue::findPending(Addr addr, int size) const
1122810SN/A{
1134666SN/A    MSHR::ConstIterator i = readyList.begin();
1144666SN/A    MSHR::ConstIterator end = readyList.end();
1152810SN/A    for (; i != end; ++i) {
1162810SN/A        MSHR *mshr = *i;
1174626SN/A        if (mshr->addr < addr) {
1184626SN/A            if (mshr->addr + mshr->size > addr) {
1192810SN/A                return mshr;
1202810SN/A            }
1212810SN/A        } else {
1224626SN/A            if (addr + size > mshr->addr) {
1232810SN/A                return mshr;
1242810SN/A            }
1252810SN/A        }
1262810SN/A    }
1272810SN/A    return NULL;
1282810SN/A}
1292810SN/A
1304666SN/A
1314666SN/AMSHR::Iterator
1324666SN/AMSHRQueue::addToReadyList(MSHR *mshr)
1334666SN/A{
1344871SN/A    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
1354666SN/A        return readyList.insert(readyList.end(), mshr);
1364666SN/A    }
1374666SN/A
1384666SN/A    MSHR::Iterator i = readyList.begin();
1394666SN/A    MSHR::Iterator end = readyList.end();
1404666SN/A    for (; i != end; ++i) {
1414871SN/A        if ((*i)->readyTime > mshr->readyTime) {
1424666SN/A            return readyList.insert(i, mshr);
1434666SN/A        }
1444666SN/A    }
1454666SN/A    assert(false);
1464904SN/A    return end;  // keep stupid compilers happy
1474666SN/A}
1484666SN/A
1494666SN/A
1504626SN/AMSHR *
1514666SN/AMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
1524666SN/A                    Tick when, Counter order)
1532810SN/A{
1543149SN/A    assert(!freeList.empty());
1552810SN/A    MSHR *mshr = freeList.front();
1562810SN/A    assert(mshr->getNumTargets() == 0);
1572810SN/A    freeList.pop_front();
1582810SN/A
1594666SN/A    mshr->allocate(addr, size, pkt, when, order);
1602810SN/A    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
1614666SN/A    mshr->readyIter = addToReadyList(mshr);
1622810SN/A
1632810SN/A    allocated += 1;
1642810SN/A    return mshr;
1652810SN/A}
1662810SN/A
1672810SN/A
1682810SN/Avoid
1694626SN/AMSHRQueue::deallocate(MSHR *mshr)
1702810SN/A{
1712810SN/A    deallocateOne(mshr);
1722810SN/A}
1732810SN/A
1742810SN/AMSHR::Iterator
1754626SN/AMSHRQueue::deallocateOne(MSHR *mshr)
1762810SN/A{
1772810SN/A    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
1782810SN/A    freeList.push_front(mshr);
1792810SN/A    allocated--;
1802810SN/A    if (mshr->inService) {
1814626SN/A        inServiceEntries--;
1822810SN/A    } else {
1834666SN/A        readyList.erase(mshr->readyIter);
1842810SN/A    }
1852810SN/A    mshr->deallocate();
1862810SN/A    return retval;
1872810SN/A}
1882810SN/A
1892810SN/Avoid
1902810SN/AMSHRQueue::moveToFront(MSHR *mshr)
1912810SN/A{
1922810SN/A    if (!mshr->inService) {
1932810SN/A        assert(mshr == *(mshr->readyIter));
1944666SN/A        readyList.erase(mshr->readyIter);
1954666SN/A        mshr->readyIter = readyList.insert(readyList.begin(), mshr);
1962810SN/A    }
1972810SN/A}
1982810SN/A
1992810SN/Avoid
2004626SN/AMSHRQueue::markInService(MSHR *mshr)
2012810SN/A{
2024908SN/A    if (mshr->markInService()) {
2032810SN/A        deallocate(mshr);
2044908SN/A    } else {
2054908SN/A        readyList.erase(mshr->readyIter);
2064908SN/A        inServiceEntries += 1;
2072810SN/A    }
2082810SN/A}
2092810SN/A
2102810SN/Avoid
2114626SN/AMSHRQueue::markPending(MSHR *mshr)
2122810SN/A{
2134666SN/A    assert(mshr->inService);
2142810SN/A    mshr->inService = false;
2154626SN/A    --inServiceEntries;
2162810SN/A    /**
2172810SN/A     * @ todo might want to add rerequests to front of pending list for
2182810SN/A     * performance.
2192810SN/A     */
2204666SN/A    mshr->readyIter = addToReadyList(mshr);
2212810SN/A}
2222810SN/A
2232810SN/Avoid
2242813SN/AMSHRQueue::squash(int threadNum)
2252810SN/A{
2262810SN/A    MSHR::Iterator i = allocatedList.begin();
2272810SN/A    MSHR::Iterator end = allocatedList.end();
2282810SN/A    for (; i != end;) {
2292810SN/A        MSHR *mshr = *i;
2302813SN/A        if (mshr->threadNum == threadNum) {
2312810SN/A            while (mshr->hasTargets()) {
2322810SN/A                mshr->popTarget();
2335715Shsul@eecs.umich.edu                assert(0/*target->req->threadId()*/ == threadNum);
2342810SN/A            }
2352810SN/A            assert(!mshr->hasTargets());
2362810SN/A            assert(mshr->ntargets==0);
2372810SN/A            if (!mshr->inService) {
2382810SN/A                i = deallocateOne(mshr);
2392810SN/A            } else {
2402810SN/A                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
2412810SN/A                ++i;
2422810SN/A            }
2432810SN/A        } else {
2442810SN/A            ++i;
2452810SN/A        }
2462810SN/A    }
2472810SN/A}
248