mshr_queue.cc revision 5314
110259SAndrew.Bardsley@arm.com/*
210259SAndrew.Bardsley@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
310259SAndrew.Bardsley@arm.com * All rights reserved.
410259SAndrew.Bardsley@arm.com *
510259SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without
610259SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are
710259SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright
810259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer;
910259SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright
1010259SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the
1110259SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution;
1210259SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its
1310259SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from
1410259SAndrew.Bardsley@arm.com * this software without specific prior written permission.
1510259SAndrew.Bardsley@arm.com *
1610259SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1710259SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1810259SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1910259SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2010259SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2110259SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2210259SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2310259SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2410259SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2510259SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2610259SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2710259SAndrew.Bardsley@arm.com *
2810259SAndrew.Bardsley@arm.com * Authors: Erik Hallnor
2910259SAndrew.Bardsley@arm.com */
3010259SAndrew.Bardsley@arm.com
3110259SAndrew.Bardsley@arm.com/** @file
3210259SAndrew.Bardsley@arm.com * Definition of MSHRQueue class functions.
3310259SAndrew.Bardsley@arm.com */
3410259SAndrew.Bardsley@arm.com
3510259SAndrew.Bardsley@arm.com#include "mem/cache/miss/mshr_queue.hh"
3610259SAndrew.Bardsley@arm.com
3710259SAndrew.Bardsley@arm.comusing namespace std;
3810259SAndrew.Bardsley@arm.com
3910259SAndrew.Bardsley@arm.comMSHRQueue::MSHRQueue(const std::string &_label,
4010259SAndrew.Bardsley@arm.com                     int num_entries, int reserve, int _index)
4110259SAndrew.Bardsley@arm.com    : label(_label),
4210259SAndrew.Bardsley@arm.com      numEntries(num_entries + reserve - 1), numReserve(reserve),
4310259SAndrew.Bardsley@arm.com      index(_index)
4410259SAndrew.Bardsley@arm.com{
4510259SAndrew.Bardsley@arm.com    allocated = 0;
4610259SAndrew.Bardsley@arm.com    inServiceEntries = 0;
4710259SAndrew.Bardsley@arm.com    registers = new MSHR[numEntries];
4810259SAndrew.Bardsley@arm.com    for (int i = 0; i < numEntries; ++i) {
4910259SAndrew.Bardsley@arm.com        registers[i].queue = this;
5010259SAndrew.Bardsley@arm.com        freeList.push_back(&registers[i]);
5110259SAndrew.Bardsley@arm.com    }
5210259SAndrew.Bardsley@arm.com}
5310259SAndrew.Bardsley@arm.com
5410259SAndrew.Bardsley@arm.comMSHRQueue::~MSHRQueue()
5510259SAndrew.Bardsley@arm.com{
5610259SAndrew.Bardsley@arm.com    delete [] registers;
5710259SAndrew.Bardsley@arm.com}
5810259SAndrew.Bardsley@arm.com
5910259SAndrew.Bardsley@arm.comMSHR *
6010259SAndrew.Bardsley@arm.comMSHRQueue::findMatch(Addr addr) const
6110259SAndrew.Bardsley@arm.com{
6210259SAndrew.Bardsley@arm.com    MSHR::ConstIterator i = allocatedList.begin();
6310259SAndrew.Bardsley@arm.com    MSHR::ConstIterator end = allocatedList.end();
6410259SAndrew.Bardsley@arm.com    for (; i != end; ++i) {
6510259SAndrew.Bardsley@arm.com        MSHR *mshr = *i;
6610259SAndrew.Bardsley@arm.com        if (mshr->addr == addr) {
6710259SAndrew.Bardsley@arm.com            return mshr;
6810259SAndrew.Bardsley@arm.com        }
6910259SAndrew.Bardsley@arm.com    }
7010259SAndrew.Bardsley@arm.com    return NULL;
7110259SAndrew.Bardsley@arm.com}
7210259SAndrew.Bardsley@arm.com
7310259SAndrew.Bardsley@arm.combool
7410259SAndrew.Bardsley@arm.comMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
7510259SAndrew.Bardsley@arm.com{
7610259SAndrew.Bardsley@arm.com    // Need an empty vector
7710259SAndrew.Bardsley@arm.com    assert(matches.empty());
7810259SAndrew.Bardsley@arm.com    bool retval = false;
7910259SAndrew.Bardsley@arm.com    MSHR::ConstIterator i = allocatedList.begin();
8010259SAndrew.Bardsley@arm.com    MSHR::ConstIterator end = allocatedList.end();
8110259SAndrew.Bardsley@arm.com    for (; i != end; ++i) {
8210259SAndrew.Bardsley@arm.com        MSHR *mshr = *i;
8310259SAndrew.Bardsley@arm.com        if (mshr->addr == addr) {
8410259SAndrew.Bardsley@arm.com            retval = true;
8510259SAndrew.Bardsley@arm.com            matches.push_back(mshr);
8610259SAndrew.Bardsley@arm.com        }
8710259SAndrew.Bardsley@arm.com    }
8810259SAndrew.Bardsley@arm.com    return retval;
8910259SAndrew.Bardsley@arm.com}
9010259SAndrew.Bardsley@arm.com
9110259SAndrew.Bardsley@arm.com
9210259SAndrew.Bardsley@arm.combool
9310259SAndrew.Bardsley@arm.comMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
9410259SAndrew.Bardsley@arm.com{
9510259SAndrew.Bardsley@arm.com    pkt->pushLabel(label);
9610259SAndrew.Bardsley@arm.com    MSHR::ConstIterator i = allocatedList.begin();
9710259SAndrew.Bardsley@arm.com    MSHR::ConstIterator end = allocatedList.end();
9810259SAndrew.Bardsley@arm.com    for (; i != end; ++i) {
9910259SAndrew.Bardsley@arm.com        MSHR *mshr = *i;
10010259SAndrew.Bardsley@arm.com        if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) {
10110259SAndrew.Bardsley@arm.com            pkt->popLabel();
10210259SAndrew.Bardsley@arm.com            return true;
10310259SAndrew.Bardsley@arm.com        }
10410259SAndrew.Bardsley@arm.com    }
10510259SAndrew.Bardsley@arm.com    pkt->popLabel();
10610259SAndrew.Bardsley@arm.com    return false;
10710259SAndrew.Bardsley@arm.com}
10810259SAndrew.Bardsley@arm.com
10910259SAndrew.Bardsley@arm.com
11010259SAndrew.Bardsley@arm.comMSHR *
11110259SAndrew.Bardsley@arm.comMSHRQueue::findPending(Addr addr, int size) const
11210259SAndrew.Bardsley@arm.com{
11310259SAndrew.Bardsley@arm.com    MSHR::ConstIterator i = readyList.begin();
11410259SAndrew.Bardsley@arm.com    MSHR::ConstIterator end = readyList.end();
11510259SAndrew.Bardsley@arm.com    for (; i != end; ++i) {
11610259SAndrew.Bardsley@arm.com        MSHR *mshr = *i;
11710259SAndrew.Bardsley@arm.com        if (mshr->addr < addr) {
11810259SAndrew.Bardsley@arm.com            if (mshr->addr + mshr->size > addr) {
11910259SAndrew.Bardsley@arm.com                return mshr;
12010259SAndrew.Bardsley@arm.com            }
12110259SAndrew.Bardsley@arm.com        } else {
12210259SAndrew.Bardsley@arm.com            if (addr + size > mshr->addr) {
12310259SAndrew.Bardsley@arm.com                return mshr;
12410259SAndrew.Bardsley@arm.com            }
12510259SAndrew.Bardsley@arm.com        }
12610259SAndrew.Bardsley@arm.com    }
12710259SAndrew.Bardsley@arm.com    return NULL;
12810259SAndrew.Bardsley@arm.com}
12910259SAndrew.Bardsley@arm.com
13010259SAndrew.Bardsley@arm.com
13110259SAndrew.Bardsley@arm.comMSHR::Iterator
13210259SAndrew.Bardsley@arm.comMSHRQueue::addToReadyList(MSHR *mshr)
13310259SAndrew.Bardsley@arm.com{
13410259SAndrew.Bardsley@arm.com    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
13510259SAndrew.Bardsley@arm.com        return readyList.insert(readyList.end(), mshr);
13610259SAndrew.Bardsley@arm.com    }
13710259SAndrew.Bardsley@arm.com
13810259SAndrew.Bardsley@arm.com    MSHR::Iterator i = readyList.begin();
13910259SAndrew.Bardsley@arm.com    MSHR::Iterator end = readyList.end();
14010259SAndrew.Bardsley@arm.com    for (; i != end; ++i) {
14110259SAndrew.Bardsley@arm.com        if ((*i)->readyTime > mshr->readyTime) {
14210259SAndrew.Bardsley@arm.com            return readyList.insert(i, mshr);
14310259SAndrew.Bardsley@arm.com        }
14410259SAndrew.Bardsley@arm.com    }
14510259SAndrew.Bardsley@arm.com    assert(false);
14610259SAndrew.Bardsley@arm.com    return end;  // keep stupid compilers happy
14710259SAndrew.Bardsley@arm.com}
14810259SAndrew.Bardsley@arm.com
14910259SAndrew.Bardsley@arm.com
15010259SAndrew.Bardsley@arm.comMSHR *
15110259SAndrew.Bardsley@arm.comMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
15210259SAndrew.Bardsley@arm.com                    Tick when, Counter order)
15310259SAndrew.Bardsley@arm.com{
15410259SAndrew.Bardsley@arm.com    assert(!freeList.empty());
15510259SAndrew.Bardsley@arm.com    MSHR *mshr = freeList.front();
15610259SAndrew.Bardsley@arm.com    assert(mshr->getNumTargets() == 0);
15710259SAndrew.Bardsley@arm.com    freeList.pop_front();
15810259SAndrew.Bardsley@arm.com
15910259SAndrew.Bardsley@arm.com    mshr->allocate(addr, size, pkt, when, order);
16010259SAndrew.Bardsley@arm.com    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
16110259SAndrew.Bardsley@arm.com    mshr->readyIter = addToReadyList(mshr);
16210259SAndrew.Bardsley@arm.com
16310259SAndrew.Bardsley@arm.com    allocated += 1;
16410259SAndrew.Bardsley@arm.com    return mshr;
16510259SAndrew.Bardsley@arm.com}
16610259SAndrew.Bardsley@arm.com
16710259SAndrew.Bardsley@arm.com
16810259SAndrew.Bardsley@arm.comvoid
16910259SAndrew.Bardsley@arm.comMSHRQueue::deallocate(MSHR *mshr)
17010259SAndrew.Bardsley@arm.com{
17110259SAndrew.Bardsley@arm.com    deallocateOne(mshr);
17210259SAndrew.Bardsley@arm.com}
17310259SAndrew.Bardsley@arm.com
17410259SAndrew.Bardsley@arm.comMSHR::Iterator
17510259SAndrew.Bardsley@arm.comMSHRQueue::deallocateOne(MSHR *mshr)
17610259SAndrew.Bardsley@arm.com{
17710259SAndrew.Bardsley@arm.com    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
17810259SAndrew.Bardsley@arm.com    freeList.push_front(mshr);
17910259SAndrew.Bardsley@arm.com    allocated--;
18010259SAndrew.Bardsley@arm.com    if (mshr->inService) {
18110259SAndrew.Bardsley@arm.com        inServiceEntries--;
18210259SAndrew.Bardsley@arm.com    } else {
18310259SAndrew.Bardsley@arm.com        readyList.erase(mshr->readyIter);
18410259SAndrew.Bardsley@arm.com    }
18510259SAndrew.Bardsley@arm.com    mshr->deallocate();
18610259SAndrew.Bardsley@arm.com    return retval;
18710259SAndrew.Bardsley@arm.com}
18810259SAndrew.Bardsley@arm.com
18910259SAndrew.Bardsley@arm.comvoid
19010259SAndrew.Bardsley@arm.comMSHRQueue::moveToFront(MSHR *mshr)
19110259SAndrew.Bardsley@arm.com{
19210259SAndrew.Bardsley@arm.com    if (!mshr->inService) {
19310259SAndrew.Bardsley@arm.com        assert(mshr == *(mshr->readyIter));
19410259SAndrew.Bardsley@arm.com        readyList.erase(mshr->readyIter);
19510259SAndrew.Bardsley@arm.com        mshr->readyIter = readyList.insert(readyList.begin(), mshr);
19610259SAndrew.Bardsley@arm.com    }
19710259SAndrew.Bardsley@arm.com}
19810259SAndrew.Bardsley@arm.com
19910259SAndrew.Bardsley@arm.comvoid
20010259SAndrew.Bardsley@arm.comMSHRQueue::markInService(MSHR *mshr)
20110259SAndrew.Bardsley@arm.com{
20210259SAndrew.Bardsley@arm.com    if (mshr->markInService()) {
20310259SAndrew.Bardsley@arm.com        deallocate(mshr);
20410259SAndrew.Bardsley@arm.com    } else {
20510259SAndrew.Bardsley@arm.com        readyList.erase(mshr->readyIter);
20610259SAndrew.Bardsley@arm.com        inServiceEntries += 1;
20710259SAndrew.Bardsley@arm.com    }
20810259SAndrew.Bardsley@arm.com}
20910259SAndrew.Bardsley@arm.com
21010259SAndrew.Bardsley@arm.comvoid
21110259SAndrew.Bardsley@arm.comMSHRQueue::markPending(MSHR *mshr)
21210259SAndrew.Bardsley@arm.com{
21310259SAndrew.Bardsley@arm.com    assert(mshr->inService);
21410259SAndrew.Bardsley@arm.com    mshr->inService = false;
21510259SAndrew.Bardsley@arm.com    --inServiceEntries;
21610259SAndrew.Bardsley@arm.com    /**
21710259SAndrew.Bardsley@arm.com     * @ todo might want to add rerequests to front of pending list for
21810259SAndrew.Bardsley@arm.com     * performance.
21910259SAndrew.Bardsley@arm.com     */
22010259SAndrew.Bardsley@arm.com    mshr->readyIter = addToReadyList(mshr);
22110259SAndrew.Bardsley@arm.com}
22210259SAndrew.Bardsley@arm.com
22310259SAndrew.Bardsley@arm.comvoid
22410259SAndrew.Bardsley@arm.comMSHRQueue::squash(int threadNum)
22510259SAndrew.Bardsley@arm.com{
22611567Smitch.hayenga@arm.com    MSHR::Iterator i = allocatedList.begin();
22711567Smitch.hayenga@arm.com    MSHR::Iterator end = allocatedList.end();
22810259SAndrew.Bardsley@arm.com    for (; i != end;) {
22910259SAndrew.Bardsley@arm.com        MSHR *mshr = *i;
23010259SAndrew.Bardsley@arm.com        if (mshr->threadNum == threadNum) {
23110259SAndrew.Bardsley@arm.com            while (mshr->hasTargets()) {
23210259SAndrew.Bardsley@arm.com                mshr->popTarget();
23310259SAndrew.Bardsley@arm.com                assert(0/*target->req->getThreadNum()*/ == threadNum);
23410259SAndrew.Bardsley@arm.com            }
23510259SAndrew.Bardsley@arm.com            assert(!mshr->hasTargets());
23610259SAndrew.Bardsley@arm.com            assert(mshr->ntargets==0);
23710259SAndrew.Bardsley@arm.com            if (!mshr->inService) {
23810259SAndrew.Bardsley@arm.com                i = deallocateOne(mshr);
23910259SAndrew.Bardsley@arm.com            } else {
24010259SAndrew.Bardsley@arm.com                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
24110259SAndrew.Bardsley@arm.com                ++i;
24210259SAndrew.Bardsley@arm.com            }
24310259SAndrew.Bardsley@arm.com        } else {
24410259SAndrew.Bardsley@arm.com            ++i;
24510259SAndrew.Bardsley@arm.com        }
24610259SAndrew.Bardsley@arm.com    }
24710259SAndrew.Bardsley@arm.com}
24810259SAndrew.Bardsley@arm.com