mshr_queue.cc revision 4920
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
322810SN/A * Definition of MSHRQueue class functions.
332810SN/A */
342810SN/A
352810SN/A#include "mem/cache/miss/mshr_queue.hh"
363348SN/A
373348SN/Ausing namespace std;
388232Snate@binkert.org
395338Sstever@gmail.comMSHRQueue::MSHRQueue(int num_entries, int reserve, int _index)
405338Sstever@gmail.com    : numEntries(num_entries + reserve - 1), numReserve(reserve),
418786Sgblack@eecs.umich.edu      index(_index)
422810SN/A{
432810SN/A    allocated = 0;
442810SN/A    inServiceEntries = 0;
454965SN/A    registers = new MSHR[numEntries];
466122SSteve.Reinhardt@amd.com    for (int i = 0; i < numEntries; ++i) {
475314SN/A        registers[i].queue = this;
488736Sandreas.hansson@arm.com        freeList.push_back(&registers[i]);
492810SN/A    }
504475SN/A}
514475SN/A
524475SN/AMSHRQueue::~MSHRQueue()
535034SN/A{
545034SN/A    delete [] registers;
555314SN/A}
565314SN/A
574628SN/AMSHR *
585034SN/AMSHRQueue::findMatch(Addr addr) const
595034SN/A{
605034SN/A    MSHR::ConstIterator i = allocatedList.begin();
616122SSteve.Reinhardt@amd.com    MSHR::ConstIterator end = allocatedList.end();
628134SAli.Saidi@ARM.com    for (; i != end; ++i) {
634626SN/A        MSHR *mshr = *i;
644626SN/A        if (mshr->addr == addr) {
655034SN/A            return mshr;
666122SSteve.Reinhardt@amd.com        }
676978SLisa.Hsu@amd.com    }
688833Sdam.sunwoo@arm.com    return NULL;
694458SN/A}
702810SN/A
712810SN/Abool
725314SN/AMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
735314SN/A{
745314SN/A    // Need an empty vector
755314SN/A    assert(matches.empty());
765314SN/A    bool retval = false;
775314SN/A    MSHR::ConstIterator i = allocatedList.begin();
785314SN/A    MSHR::ConstIterator end = allocatedList.end();
795314SN/A    for (; i != end; ++i) {
805314SN/A        MSHR *mshr = *i;
815314SN/A        if (mshr->addr == addr) {
825314SN/A            retval = true;
836227Snate@binkert.org            matches.push_back(mshr);
846227Snate@binkert.org        }
852810SN/A    }
862810SN/A    return retval;
872810SN/A}
882810SN/A
893606SN/A
904458SN/Abool
914458SN/AMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
923013SN/A{
933236SN/A    MSHR::ConstIterator i = allocatedList.begin();
944458SN/A    MSHR::ConstIterator end = allocatedList.end();
954458SN/A    for (; i != end; ++i) {
964458SN/A        MSHR *mshr = *i;
973246SN/A        if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) {
983309SN/A            return true;
993013SN/A        }
1002810SN/A    }
1012810SN/A    return false;
1023013SN/A}
1033013SN/A
1042810SN/A
1053013SN/AMSHR *
1063013SN/AMSHRQueue::findPending(Addr addr, int size) const
1072810SN/A{
1082810SN/A    MSHR::ConstIterator i = readyList.begin();
1092810SN/A    MSHR::ConstIterator end = readyList.end();
1102810SN/A    for (; i != end; ++i) {
1112810SN/A        MSHR *mshr = *i;
1123013SN/A        if (mshr->addr < addr) {
1133013SN/A            if (mshr->addr + mshr->size > addr) {
1143013SN/A                return mshr;
1152897SN/A            }
1162897SN/A        } else {
1173013SN/A            if (addr + size > mshr->addr) {
1182897SN/A                return mshr;
1194666SN/A            }
1204666SN/A        }
1218708Sandreas.hansson@arm.com    }
1222897SN/A    return NULL;
1232810SN/A}
1242810SN/A
1252844SN/A
1262810SN/AMSHR::Iterator
1272858SN/AMSHRQueue::addToReadyList(MSHR *mshr)
1282858SN/A{
1292858SN/A    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
1302858SN/A        return readyList.insert(readyList.end(), mshr);
1318711Sandreas.hansson@arm.com    }
1322858SN/A
1332858SN/A    MSHR::Iterator i = readyList.begin();
1344628SN/A    MSHR::Iterator end = readyList.end();
1352858SN/A    for (; i != end; ++i) {
1362810SN/A        if ((*i)->readyTime > mshr->readyTime) {
1372810SN/A            return readyList.insert(i, mshr);
1382810SN/A        }
1392810SN/A    }
1402810SN/A    assert(false);
1414022SN/A    return end;  // keep stupid compilers happy
1424022SN/A}
1434022SN/A
1442810SN/A
1452810SN/AMSHR *
1468833Sdam.sunwoo@arm.comMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
1472810SN/A                    Tick when, Counter order)
1482810SN/A{
1492810SN/A    assert(!freeList.empty());
1502810SN/A    MSHR *mshr = freeList.front();
1518833Sdam.sunwoo@arm.com    assert(mshr->getNumTargets() == 0);
1528833Sdam.sunwoo@arm.com    freeList.pop_front();
1538833Sdam.sunwoo@arm.com
1542810SN/A    mshr->allocate(addr, size, pkt, when, order);
1552810SN/A    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
1564871SN/A    mshr->readyIter = addToReadyList(mshr);
1574871SN/A
1584871SN/A    allocated += 1;
1594871SN/A    return mshr;
1604871SN/A}
1614871SN/A
1624871SN/A
1634871SN/Avoid
1644871SN/AMSHRQueue::deallocate(MSHR *mshr)
1654871SN/A{
1662810SN/A    deallocateOne(mshr);
1672810SN/A}
1682810SN/A
1698833Sdam.sunwoo@arm.comMSHR::Iterator
1702810SN/AMSHRQueue::deallocateOne(MSHR *mshr)
1714871SN/A{
1728833Sdam.sunwoo@arm.com    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
1738833Sdam.sunwoo@arm.com    freeList.push_front(mshr);
1748833Sdam.sunwoo@arm.com    allocated--;
1752810SN/A    if (mshr->inService) {
1762810SN/A        inServiceEntries--;
1772810SN/A    } else {
1782810SN/A        readyList.erase(mshr->readyIter);
1798833Sdam.sunwoo@arm.com    }
1802810SN/A    mshr->deallocate();
1814871SN/A    return retval;
1828833Sdam.sunwoo@arm.com}
1838833Sdam.sunwoo@arm.com
1848833Sdam.sunwoo@arm.comvoid
1852810SN/AMSHRQueue::moveToFront(MSHR *mshr)
1862810SN/A{
1874022SN/A    if (!mshr->inService) {
1884022SN/A        assert(mshr == *(mshr->readyIter));
1894022SN/A        readyList.erase(mshr->readyIter);
1902810SN/A        mshr->readyIter = readyList.insert(readyList.begin(), mshr);
1912810SN/A    }
1928833Sdam.sunwoo@arm.com}
1932810SN/A
1942810SN/Avoid
1952810SN/AMSHRQueue::markInService(MSHR *mshr)
1962810SN/A{
1978833Sdam.sunwoo@arm.com    if (mshr->markInService()) {
1988833Sdam.sunwoo@arm.com        deallocate(mshr);
1998833Sdam.sunwoo@arm.com    } else {
2002810SN/A        readyList.erase(mshr->readyIter);
2012810SN/A        inServiceEntries += 1;
2022810SN/A    }
2032810SN/A}
2042810SN/A
2058833Sdam.sunwoo@arm.comvoid
2062810SN/AMSHRQueue::markPending(MSHR *mshr)
2074871SN/A{
2088833Sdam.sunwoo@arm.com    assert(mshr->inService);
2098833Sdam.sunwoo@arm.com    mshr->inService = false;
2108833Sdam.sunwoo@arm.com    --inServiceEntries;
2112810SN/A    /**
2122810SN/A     * @ todo might want to add rerequests to front of pending list for
2132810SN/A     * performance.
2142810SN/A     */
2158833Sdam.sunwoo@arm.com    mshr->readyIter = addToReadyList(mshr);
2162810SN/A}
2174871SN/A
2188833Sdam.sunwoo@arm.comvoid
2198833Sdam.sunwoo@arm.comMSHRQueue::squash(int threadNum)
2208833Sdam.sunwoo@arm.com{
2212810SN/A    MSHR::Iterator i = allocatedList.begin();
2222810SN/A    MSHR::Iterator end = allocatedList.end();
2234022SN/A    for (; i != end;) {
2244022SN/A        MSHR *mshr = *i;
2254022SN/A        if (mshr->threadNum == threadNum) {
2262810SN/A            while (mshr->hasTargets()) {
2272810SN/A                mshr->popTarget();
2288833Sdam.sunwoo@arm.com                assert(0/*target->req->getThreadNum()*/ == threadNum);
2292810SN/A            }
2302810SN/A            assert(!mshr->hasTargets());
2312810SN/A            assert(mshr->ntargets==0);
2322810SN/A            if (!mshr->inService) {
2338833Sdam.sunwoo@arm.com                i = deallocateOne(mshr);
2348833Sdam.sunwoo@arm.com            } else {
2358833Sdam.sunwoo@arm.com                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
2362810SN/A                ++i;
2372810SN/A            }
2382810SN/A        } else {
2392810SN/A            ++i;
2402810SN/A        }
2418833Sdam.sunwoo@arm.com    }
2422810SN/A}
2434871SN/A