mshr_queue.cc revision 4908
12810SN/A/*
29725Sandreas.hansson@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
39347SAndreas.Sandberg@arm.com * All rights reserved.
49347SAndreas.Sandberg@arm.com *
59347SAndreas.Sandberg@arm.com * Redistribution and use in source and binary forms, with or without
69347SAndreas.Sandberg@arm.com * modification, are permitted provided that the following conditions are
79347SAndreas.Sandberg@arm.com * met: redistributions of source code must retain the above copyright
89347SAndreas.Sandberg@arm.com * notice, this list of conditions and the following disclaimer;
99347SAndreas.Sandberg@arm.com * redistributions in binary form must reproduce the above copyright
109347SAndreas.Sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
119347SAndreas.Sandberg@arm.com * documentation and/or other materials provided with the distribution;
129347SAndreas.Sandberg@arm.com * neither the name of the copyright holders nor the names of its
139347SAndreas.Sandberg@arm.com * 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"
362810SN/A
372810SN/Ausing namespace std;
382810SN/A
392810SN/AMSHRQueue::MSHRQueue(int num_entries, int reserve, int _index)
402810SN/A    : numEntries(num_entries + reserve - 1), numReserve(reserve),
419347SAndreas.Sandberg@arm.com      index(_index)
422810SN/A{
432810SN/A    allocated = 0;
442810SN/A    inServiceEntries = 0;
454626SN/A    registers = new MSHR[numEntries];
462810SN/A    for (int i = 0; i < numEntries; ++i) {
472810SN/A        registers[i].queue = this;
4810509SAli.Saidi@ARM.com        freeList.push_back(&registers[i]);
495338Sstever@gmail.com    }
5010509SAli.Saidi@ARM.com}
512810SN/A
522810SN/AMSHRQueue::~MSHRQueue()
532810SN/A{
545314SN/A    delete [] registers;
5510622Smitch.hayenga@arm.com}
5610622Smitch.hayenga@arm.com
579725Sandreas.hansson@arm.comMSHR *
5810622Smitch.hayenga@arm.comMSHRQueue::findMatch(Addr addr) const
5910622Smitch.hayenga@arm.com{
6010622Smitch.hayenga@arm.com    MSHR::ConstIterator i = allocatedList.begin();
612810SN/A    MSHR::ConstIterator end = allocatedList.end();
624626SN/A    for (; i != end; ++i) {
634626SN/A        MSHR *mshr = *i;
642810SN/A        if (mshr->addr == addr) {
652810SN/A            return mshr;
662810SN/A        }
672810SN/A    }
684626SN/A    return NULL;
6910028SGiacomo.Gabrielli@arm.com}
702810SN/A
712810SN/Abool
722810SN/AMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
732810SN/A{
742810SN/A    // Need an empty vector
7510028SGiacomo.Gabrielli@arm.com    assert(matches.empty());
762810SN/A    bool retval = false;
772810SN/A    MSHR::ConstIterator i = allocatedList.begin();
782810SN/A    MSHR::ConstIterator end = allocatedList.end();
792810SN/A    for (; i != end; ++i) {
802810SN/A        MSHR *mshr = *i;
812810SN/A        if (mshr->addr == addr) {
822810SN/A            retval = true;
8310028SGiacomo.Gabrielli@arm.com            matches.push_back(mshr);
842810SN/A        }
852810SN/A    }
862810SN/A    return retval;
872810SN/A
882810SN/A}
892810SN/A
902810SN/AMSHR *
912810SN/AMSHRQueue::findPending(Addr addr, int size) const
9210028SGiacomo.Gabrielli@arm.com{
932810SN/A    MSHR::ConstIterator i = readyList.begin();
942810SN/A    MSHR::ConstIterator end = readyList.end();
952810SN/A    for (; i != end; ++i) {
962810SN/A        MSHR *mshr = *i;
972810SN/A        if (mshr->addr < addr) {
984920SN/A            if (mshr->addr + mshr->size > addr) {
992810SN/A                return mshr;
1004920SN/A            }
1014920SN/A        } else {
1024920SN/A            if (addr + size > mshr->addr) {
1034920SN/A                return mshr;
1045314SN/A            }
1054920SN/A        }
1064920SN/A    }
1074920SN/A    return NULL;
1084920SN/A}
1094920SN/A
1105314SN/A
1114920SN/AMSHR::Iterator
1124920SN/AMSHRQueue::addToReadyList(MSHR *mshr)
1134920SN/A{
1145314SN/A    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
1154920SN/A        return readyList.insert(readyList.end(), mshr);
1162810SN/A    }
1172810SN/A
1184920SN/A    MSHR::Iterator i = readyList.begin();
1194626SN/A    MSHR::Iterator end = readyList.end();
12010028SGiacomo.Gabrielli@arm.com    for (; i != end; ++i) {
1212810SN/A        if ((*i)->readyTime > mshr->readyTime) {
1224666SN/A            return readyList.insert(i, mshr);
1234666SN/A        }
1242810SN/A    }
1252810SN/A    assert(false);
12610028SGiacomo.Gabrielli@arm.com    return end;  // keep stupid compilers happy
12710028SGiacomo.Gabrielli@arm.com}
12810028SGiacomo.Gabrielli@arm.com
12910028SGiacomo.Gabrielli@arm.com
13010028SGiacomo.Gabrielli@arm.comMSHR *
13110028SGiacomo.Gabrielli@arm.comMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
13210028SGiacomo.Gabrielli@arm.com                    Tick when, Counter order)
1332810SN/A{
1342810SN/A    assert(!freeList.empty());
1352810SN/A    MSHR *mshr = freeList.front();
1362810SN/A    assert(mshr->getNumTargets() == 0);
1372810SN/A    freeList.pop_front();
1382810SN/A
1394666SN/A    mshr->allocate(addr, size, pkt, when, order);
1404666SN/A    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
1414666SN/A    mshr->readyIter = addToReadyList(mshr);
1424666SN/A
1434871SN/A    allocated += 1;
1444666SN/A    return mshr;
1454666SN/A}
1464666SN/A
1474666SN/A
1484666SN/Avoid
1494666SN/AMSHRQueue::deallocate(MSHR *mshr)
1504871SN/A{
1514666SN/A    deallocateOne(mshr);
1524666SN/A}
1534666SN/A
1544666SN/AMSHR::Iterator
1554904SN/AMSHRQueue::deallocateOne(MSHR *mshr)
1564666SN/A{
1574666SN/A    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
1584666SN/A    freeList.push_front(mshr);
1594626SN/A    allocated--;
1604666SN/A    if (mshr->inService) {
1614666SN/A        inServiceEntries--;
1622810SN/A    } else {
1633149SN/A        readyList.erase(mshr->readyIter);
1642810SN/A    }
1652810SN/A    mshr->deallocate();
1662810SN/A    return retval;
1672810SN/A}
1684666SN/A
1692810SN/Avoid
1704666SN/AMSHRQueue::moveToFront(MSHR *mshr)
1712810SN/A{
1722810SN/A    if (!mshr->inService) {
1732810SN/A        assert(mshr == *(mshr->readyIter));
1742810SN/A        readyList.erase(mshr->readyIter);
1752810SN/A        mshr->readyIter = readyList.insert(readyList.begin(), mshr);
1762810SN/A    }
1772810SN/A}
1784626SN/A
1792810SN/Avoid
1802810SN/AMSHRQueue::markInService(MSHR *mshr)
1812810SN/A{
1822810SN/A    if (mshr->markInService()) {
1832810SN/A        deallocate(mshr);
1844626SN/A    } else {
1852810SN/A        readyList.erase(mshr->readyIter);
1862810SN/A        inServiceEntries += 1;
1872810SN/A    }
1882810SN/A}
1892810SN/A
1904626SN/Avoid
1912810SN/AMSHRQueue::markPending(MSHR *mshr)
1924666SN/A{
1932810SN/A    assert(mshr->inService);
1942810SN/A    mshr->inService = false;
1959347SAndreas.Sandberg@arm.com    --inServiceEntries;
1969347SAndreas.Sandberg@arm.com    /**
1979347SAndreas.Sandberg@arm.com     * @ todo might want to add rerequests to front of pending list for
19810509SAli.Saidi@ARM.com     * performance.
1999347SAndreas.Sandberg@arm.com     */
2009347SAndreas.Sandberg@arm.com    mshr->readyIter = addToReadyList(mshr);
2019347SAndreas.Sandberg@arm.com}
2029347SAndreas.Sandberg@arm.com
2032810SN/Avoid
2042810SN/AMSHRQueue::squash(int threadNum)
2052810SN/A{
2062810SN/A    MSHR::Iterator i = allocatedList.begin();
2072810SN/A    MSHR::Iterator end = allocatedList.end();
2082810SN/A    for (; i != end;) {
2092810SN/A        MSHR *mshr = *i;
2102810SN/A        if (mshr->threadNum == threadNum) {
2114666SN/A            while (mshr->hasTargets()) {
2124666SN/A                mshr->popTarget();
2132810SN/A                assert(0/*target->req->getThreadNum()*/ == threadNum);
2142810SN/A            }
2152810SN/A            assert(!mshr->hasTargets());
2162810SN/A            assert(mshr->ntargets==0);
21710679Sandreas.hansson@arm.com            if (!mshr->inService) {
2182810SN/A                i = deallocateOne(mshr);
21910679Sandreas.hansson@arm.com            } else {
2202810SN/A                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
2214908SN/A                ++i;
2224908SN/A            }
2234908SN/A        } else {
2242810SN/A            ++i;
2252810SN/A        }
2262810SN/A    }
2272810SN/A}
2284626SN/A