mshr_queue.cc revision 5314
12810Srdreslin@umich.edu/*
211051Sandreas.hansson@arm.com * Copyright (c) 2003-2005 The Regents of The University of Michigan
311051Sandreas.hansson@arm.com * All rights reserved.
411051Sandreas.hansson@arm.com *
511051Sandreas.hansson@arm.com * Redistribution and use in source and binary forms, with or without
611051Sandreas.hansson@arm.com * modification, are permitted provided that the following conditions are
711051Sandreas.hansson@arm.com * met: redistributions of source code must retain the above copyright
811051Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer;
911051Sandreas.hansson@arm.com * redistributions in binary form must reproduce the above copyright
1011051Sandreas.hansson@arm.com * notice, this list of conditions and the following disclaimer in the
1111051Sandreas.hansson@arm.com * documentation and/or other materials provided with the distribution;
1211051Sandreas.hansson@arm.com * neither the name of the copyright holders nor the names of its
1311051Sandreas.hansson@arm.com * contributors may be used to endorse or promote products derived from
1411051Sandreas.hansson@arm.com * this software without specific prior written permission.
1511051Sandreas.hansson@arm.com *
162810Srdreslin@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172810Srdreslin@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182810Srdreslin@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192810Srdreslin@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202810Srdreslin@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212810Srdreslin@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222810Srdreslin@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232810Srdreslin@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242810Srdreslin@umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252810Srdreslin@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262810Srdreslin@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272810Srdreslin@umich.edu *
282810Srdreslin@umich.edu * Authors: Erik Hallnor
292810Srdreslin@umich.edu */
302810Srdreslin@umich.edu
312810Srdreslin@umich.edu/** @file
322810Srdreslin@umich.edu * Definition of MSHRQueue class functions.
332810Srdreslin@umich.edu */
342810Srdreslin@umich.edu
352810Srdreslin@umich.edu#include "mem/cache/miss/mshr_queue.hh"
362810Srdreslin@umich.edu
372810Srdreslin@umich.eduusing namespace std;
382810Srdreslin@umich.edu
392810Srdreslin@umich.eduMSHRQueue::MSHRQueue(const std::string &_label,
402810Srdreslin@umich.edu                     int num_entries, int reserve, int _index)
412810Srdreslin@umich.edu    : label(_label),
4211051Sandreas.hansson@arm.com      numEntries(num_entries + reserve - 1), numReserve(reserve),
4311051Sandreas.hansson@arm.com      index(_index)
442810Srdreslin@umich.edu{
4511051Sandreas.hansson@arm.com    allocated = 0;
4611051Sandreas.hansson@arm.com    inServiceEntries = 0;
472810Srdreslin@umich.edu    registers = new MSHR[numEntries];
482810Srdreslin@umich.edu    for (int i = 0; i < numEntries; ++i) {
492810Srdreslin@umich.edu        registers[i].queue = this;
502810Srdreslin@umich.edu        freeList.push_back(&registers[i]);
5111051Sandreas.hansson@arm.com    }
522810Srdreslin@umich.edu}
532810Srdreslin@umich.edu
5411051Sandreas.hansson@arm.comMSHRQueue::~MSHRQueue()
552810Srdreslin@umich.edu{
5611051Sandreas.hansson@arm.com    delete [] registers;
5711051Sandreas.hansson@arm.com}
5811051Sandreas.hansson@arm.com
5911051Sandreas.hansson@arm.comMSHR *
6011051Sandreas.hansson@arm.comMSHRQueue::findMatch(Addr addr) const
6111051Sandreas.hansson@arm.com{
6211051Sandreas.hansson@arm.com    MSHR::ConstIterator i = allocatedList.begin();
6311051Sandreas.hansson@arm.com    MSHR::ConstIterator end = allocatedList.end();
6411051Sandreas.hansson@arm.com    for (; i != end; ++i) {
6511051Sandreas.hansson@arm.com        MSHR *mshr = *i;
6611053Sandreas.hansson@arm.com        if (mshr->addr == addr) {
6711053Sandreas.hansson@arm.com            return mshr;
6811051Sandreas.hansson@arm.com        }
6911051Sandreas.hansson@arm.com    }
7011051Sandreas.hansson@arm.com    return NULL;
7111197Sandreas.hansson@arm.com}
7211197Sandreas.hansson@arm.com
7311199Sandreas.hansson@arm.combool
7411197Sandreas.hansson@arm.comMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
7511197Sandreas.hansson@arm.com{
7611197Sandreas.hansson@arm.com    // Need an empty vector
7711051Sandreas.hansson@arm.com    assert(matches.empty());
7811051Sandreas.hansson@arm.com    bool retval = false;
7911051Sandreas.hansson@arm.com    MSHR::ConstIterator i = allocatedList.begin();
8011051Sandreas.hansson@arm.com    MSHR::ConstIterator end = allocatedList.end();
8111051Sandreas.hansson@arm.com    for (; i != end; ++i) {
8211051Sandreas.hansson@arm.com        MSHR *mshr = *i;
8311051Sandreas.hansson@arm.com        if (mshr->addr == addr) {
8411051Sandreas.hansson@arm.com            retval = true;
8511051Sandreas.hansson@arm.com            matches.push_back(mshr);
8611051Sandreas.hansson@arm.com        }
8711051Sandreas.hansson@arm.com    }
8811051Sandreas.hansson@arm.com    return retval;
8911051Sandreas.hansson@arm.com}
9011051Sandreas.hansson@arm.com
9111051Sandreas.hansson@arm.com
9211051Sandreas.hansson@arm.combool
9311051Sandreas.hansson@arm.comMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
9411051Sandreas.hansson@arm.com{
9511051Sandreas.hansson@arm.com    pkt->pushLabel(label);
9611051Sandreas.hansson@arm.com    MSHR::ConstIterator i = allocatedList.begin();
9711051Sandreas.hansson@arm.com    MSHR::ConstIterator end = allocatedList.end();
9811051Sandreas.hansson@arm.com    for (; i != end; ++i) {
9911051Sandreas.hansson@arm.com        MSHR *mshr = *i;
10011051Sandreas.hansson@arm.com        if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) {
10111051Sandreas.hansson@arm.com            pkt->popLabel();
10211051Sandreas.hansson@arm.com            return true;
10311051Sandreas.hansson@arm.com        }
10411051Sandreas.hansson@arm.com    }
10511051Sandreas.hansson@arm.com    pkt->popLabel();
10611051Sandreas.hansson@arm.com    return false;
10711051Sandreas.hansson@arm.com}
10811051Sandreas.hansson@arm.com
10911051Sandreas.hansson@arm.com
11011051Sandreas.hansson@arm.comMSHR *
11111051Sandreas.hansson@arm.comMSHRQueue::findPending(Addr addr, int size) const
11211051Sandreas.hansson@arm.com{
11311051Sandreas.hansson@arm.com    MSHR::ConstIterator i = readyList.begin();
11411051Sandreas.hansson@arm.com    MSHR::ConstIterator end = readyList.end();
11511051Sandreas.hansson@arm.com    for (; i != end; ++i) {
11611051Sandreas.hansson@arm.com        MSHR *mshr = *i;
11711051Sandreas.hansson@arm.com        if (mshr->addr < addr) {
11811051Sandreas.hansson@arm.com            if (mshr->addr + mshr->size > addr) {
11911051Sandreas.hansson@arm.com                return mshr;
12011051Sandreas.hansson@arm.com            }
12111051Sandreas.hansson@arm.com        } else {
12211051Sandreas.hansson@arm.com            if (addr + size > mshr->addr) {
12311051Sandreas.hansson@arm.com                return mshr;
12411051Sandreas.hansson@arm.com            }
12511051Sandreas.hansson@arm.com        }
12611051Sandreas.hansson@arm.com    }
12711051Sandreas.hansson@arm.com    return NULL;
12811051Sandreas.hansson@arm.com}
12911051Sandreas.hansson@arm.com
13011051Sandreas.hansson@arm.com
13111051Sandreas.hansson@arm.comMSHR::Iterator
13211051Sandreas.hansson@arm.comMSHRQueue::addToReadyList(MSHR *mshr)
13311051Sandreas.hansson@arm.com{
13411051Sandreas.hansson@arm.com    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
13511051Sandreas.hansson@arm.com        return readyList.insert(readyList.end(), mshr);
13611051Sandreas.hansson@arm.com    }
13711051Sandreas.hansson@arm.com
13811051Sandreas.hansson@arm.com    MSHR::Iterator i = readyList.begin();
13911051Sandreas.hansson@arm.com    MSHR::Iterator end = readyList.end();
14011051Sandreas.hansson@arm.com    for (; i != end; ++i) {
14111051Sandreas.hansson@arm.com        if ((*i)->readyTime > mshr->readyTime) {
14211051Sandreas.hansson@arm.com            return readyList.insert(i, mshr);
14311051Sandreas.hansson@arm.com        }
14411051Sandreas.hansson@arm.com    }
14511051Sandreas.hansson@arm.com    assert(false);
14611051Sandreas.hansson@arm.com    return end;  // keep stupid compilers happy
14711051Sandreas.hansson@arm.com}
14811051Sandreas.hansson@arm.com
14911051Sandreas.hansson@arm.com
15011051Sandreas.hansson@arm.comMSHR *
15111051Sandreas.hansson@arm.comMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
15211051Sandreas.hansson@arm.com                    Tick when, Counter order)
15311051Sandreas.hansson@arm.com{
15411051Sandreas.hansson@arm.com    assert(!freeList.empty());
15511051Sandreas.hansson@arm.com    MSHR *mshr = freeList.front();
15611051Sandreas.hansson@arm.com    assert(mshr->getNumTargets() == 0);
15711051Sandreas.hansson@arm.com    freeList.pop_front();
15811051Sandreas.hansson@arm.com
15911051Sandreas.hansson@arm.com    mshr->allocate(addr, size, pkt, when, order);
16011051Sandreas.hansson@arm.com    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
16111051Sandreas.hansson@arm.com    mshr->readyIter = addToReadyList(mshr);
16211051Sandreas.hansson@arm.com
16311051Sandreas.hansson@arm.com    allocated += 1;
16411051Sandreas.hansson@arm.com    return mshr;
16511051Sandreas.hansson@arm.com}
16611051Sandreas.hansson@arm.com
16711051Sandreas.hansson@arm.com
16811051Sandreas.hansson@arm.comvoid
16911051Sandreas.hansson@arm.comMSHRQueue::deallocate(MSHR *mshr)
17011051Sandreas.hansson@arm.com{
17111051Sandreas.hansson@arm.com    deallocateOne(mshr);
17211051Sandreas.hansson@arm.com}
17311051Sandreas.hansson@arm.com
17411051Sandreas.hansson@arm.comMSHR::Iterator
17511051Sandreas.hansson@arm.comMSHRQueue::deallocateOne(MSHR *mshr)
17611051Sandreas.hansson@arm.com{
17711051Sandreas.hansson@arm.com    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
17811051Sandreas.hansson@arm.com    freeList.push_front(mshr);
17911051Sandreas.hansson@arm.com    allocated--;
18011051Sandreas.hansson@arm.com    if (mshr->inService) {
18111051Sandreas.hansson@arm.com        inServiceEntries--;
18211051Sandreas.hansson@arm.com    } else {
18311051Sandreas.hansson@arm.com        readyList.erase(mshr->readyIter);
18411051Sandreas.hansson@arm.com    }
18511051Sandreas.hansson@arm.com    mshr->deallocate();
18611051Sandreas.hansson@arm.com    return retval;
18711051Sandreas.hansson@arm.com}
18811051Sandreas.hansson@arm.com
18911051Sandreas.hansson@arm.comvoid
19011051Sandreas.hansson@arm.comMSHRQueue::moveToFront(MSHR *mshr)
19111051Sandreas.hansson@arm.com{
19211051Sandreas.hansson@arm.com    if (!mshr->inService) {
19311051Sandreas.hansson@arm.com        assert(mshr == *(mshr->readyIter));
19411051Sandreas.hansson@arm.com        readyList.erase(mshr->readyIter);
19511051Sandreas.hansson@arm.com        mshr->readyIter = readyList.insert(readyList.begin(), mshr);
19611051Sandreas.hansson@arm.com    }
19711051Sandreas.hansson@arm.com}
19811051Sandreas.hansson@arm.com
19911051Sandreas.hansson@arm.comvoid
20011051Sandreas.hansson@arm.comMSHRQueue::markInService(MSHR *mshr)
20111051Sandreas.hansson@arm.com{
20211051Sandreas.hansson@arm.com    if (mshr->markInService()) {
20311051Sandreas.hansson@arm.com        deallocate(mshr);
20411051Sandreas.hansson@arm.com    } else {
20511051Sandreas.hansson@arm.com        readyList.erase(mshr->readyIter);
20611197Sandreas.hansson@arm.com        inServiceEntries += 1;
20711197Sandreas.hansson@arm.com    }
20811197Sandreas.hansson@arm.com}
20911197Sandreas.hansson@arm.com
21011051Sandreas.hansson@arm.comvoid
21111051Sandreas.hansson@arm.comMSHRQueue::markPending(MSHR *mshr)
21211051Sandreas.hansson@arm.com{
21311051Sandreas.hansson@arm.com    assert(mshr->inService);
21411051Sandreas.hansson@arm.com    mshr->inService = false;
21511051Sandreas.hansson@arm.com    --inServiceEntries;
21611051Sandreas.hansson@arm.com    /**
21711051Sandreas.hansson@arm.com     * @ todo might want to add rerequests to front of pending list for
21811051Sandreas.hansson@arm.com     * performance.
21911051Sandreas.hansson@arm.com     */
22011051Sandreas.hansson@arm.com    mshr->readyIter = addToReadyList(mshr);
22111051Sandreas.hansson@arm.com}
22211051Sandreas.hansson@arm.com
22311051Sandreas.hansson@arm.comvoid
22411051Sandreas.hansson@arm.comMSHRQueue::squash(int threadNum)
22511051Sandreas.hansson@arm.com{
22611051Sandreas.hansson@arm.com    MSHR::Iterator i = allocatedList.begin();
22711051Sandreas.hansson@arm.com    MSHR::Iterator end = allocatedList.end();
22811197Sandreas.hansson@arm.com    for (; i != end;) {
22911197Sandreas.hansson@arm.com        MSHR *mshr = *i;
23011051Sandreas.hansson@arm.com        if (mshr->threadNum == threadNum) {
23111197Sandreas.hansson@arm.com            while (mshr->hasTargets()) {
23211197Sandreas.hansson@arm.com                mshr->popTarget();
23311197Sandreas.hansson@arm.com                assert(0/*target->req->getThreadNum()*/ == threadNum);
23411197Sandreas.hansson@arm.com            }
23511197Sandreas.hansson@arm.com            assert(!mshr->hasTargets());
23611197Sandreas.hansson@arm.com            assert(mshr->ntargets==0);
23711197Sandreas.hansson@arm.com            if (!mshr->inService) {
23811197Sandreas.hansson@arm.com                i = deallocateOne(mshr);
23911197Sandreas.hansson@arm.com            } else {
24011197Sandreas.hansson@arm.com                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
24111197Sandreas.hansson@arm.com                ++i;
24211197Sandreas.hansson@arm.com            }
24311197Sandreas.hansson@arm.com        } else {
24411197Sandreas.hansson@arm.com            ++i;
24511051Sandreas.hansson@arm.com        }
24611197Sandreas.hansson@arm.com    }
24711197Sandreas.hansson@arm.com}
24811197Sandreas.hansson@arm.com