mshr_queue.cc revision 3149
1955SN/A/*
2955SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
31762SN/A * All rights reserved.
4955SN/A *
5955SN/A * Redistribution and use in source and binary forms, with or without
6955SN/A * modification, are permitted provided that the following conditions are
7955SN/A * met: redistributions of source code must retain the above copyright
8955SN/A * notice, this list of conditions and the following disclaimer;
9955SN/A * redistributions in binary form must reproduce the above copyright
10955SN/A * notice, this list of conditions and the following disclaimer in the
11955SN/A * documentation and/or other materials provided with the distribution;
12955SN/A * neither the name of the copyright holders nor the names of its
13955SN/A * contributors may be used to endorse or promote products derived from
14955SN/A * this software without specific prior written permission.
15955SN/A *
16955SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17955SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18955SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19955SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20955SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21955SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22955SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23955SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24955SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25955SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26955SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27955SN/A *
28955SN/A * Authors: Erik Hallnor
29955SN/A */
30955SN/A
31955SN/A/** @file
32955SN/A * Definition of the MSHRQueue.
332632Sstever@eecs.umich.edu */
342632Sstever@eecs.umich.edu
352632Sstever@eecs.umich.edu#include "mem/cache/miss/mshr_queue.hh"
362632Sstever@eecs.umich.edu#include "sim/eventq.hh"
37955SN/A
382632Sstever@eecs.umich.eduusing namespace std;
392632Sstever@eecs.umich.edu
402632Sstever@eecs.umich.eduMSHRQueue::MSHRQueue(int num_mshrs, int reserve)
412632Sstever@eecs.umich.edu    : numMSHRs(num_mshrs + reserve - 1), numReserve(reserve)
422632Sstever@eecs.umich.edu{
432632Sstever@eecs.umich.edu    allocated = 0;
442632Sstever@eecs.umich.edu    inServiceMSHRs = 0;
452632Sstever@eecs.umich.edu    allocatedTargets = 0;
462632Sstever@eecs.umich.edu    registers = new MSHR[numMSHRs];
472632Sstever@eecs.umich.edu    for (int i = 0; i < numMSHRs; ++i) {
482632Sstever@eecs.umich.edu        freeList.push_back(&registers[i]);
492632Sstever@eecs.umich.edu    }
502632Sstever@eecs.umich.edu}
512632Sstever@eecs.umich.edu
522632Sstever@eecs.umich.eduMSHRQueue::~MSHRQueue()
532632Sstever@eecs.umich.edu{
542632Sstever@eecs.umich.edu    delete [] registers;
552632Sstever@eecs.umich.edu}
562632Sstever@eecs.umich.edu
572632Sstever@eecs.umich.eduMSHR*
58955SN/AMSHRQueue::findMatch(Addr addr) const
59955SN/A{
60955SN/A    MSHR::ConstIterator i = allocatedList.begin();
61955SN/A    MSHR::ConstIterator end = allocatedList.end();
62955SN/A    for (; i != end; ++i) {
63955SN/A        MSHR *mshr = *i;
64955SN/A        if (mshr->addr == addr) {
651858SN/A            return mshr;
661858SN/A        }
672653Sstever@eecs.umich.edu    }
682653Sstever@eecs.umich.edu    return NULL;
692653Sstever@eecs.umich.edu}
702653Sstever@eecs.umich.edu
712653Sstever@eecs.umich.edubool
722653Sstever@eecs.umich.eduMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
732653Sstever@eecs.umich.edu{
742653Sstever@eecs.umich.edu    // Need an empty vector
752653Sstever@eecs.umich.edu    assert(matches.empty());
762653Sstever@eecs.umich.edu    bool retval = false;
772653Sstever@eecs.umich.edu    MSHR::ConstIterator i = allocatedList.begin();
781852SN/A    MSHR::ConstIterator end = allocatedList.end();
79955SN/A    for (; i != end; ++i) {
80955SN/A        MSHR *mshr = *i;
81955SN/A        if (mshr->addr == addr) {
822632Sstever@eecs.umich.edu            retval = true;
832632Sstever@eecs.umich.edu            matches.push_back(mshr);
84955SN/A        }
851533SN/A    }
862632Sstever@eecs.umich.edu    return retval;
871533SN/A
88955SN/A}
89955SN/A
902632Sstever@eecs.umich.eduMSHR*
912632Sstever@eecs.umich.eduMSHRQueue::findPending(Packet * &pkt) const
92955SN/A{
93955SN/A    MSHR::ConstIterator i = pendingList.begin();
94955SN/A    MSHR::ConstIterator end = pendingList.end();
95955SN/A    for (; i != end; ++i) {
962632Sstever@eecs.umich.edu        MSHR *mshr = *i;
97955SN/A        if (mshr->addr < pkt->getAddr()) {
982632Sstever@eecs.umich.edu            if (mshr->addr + mshr->pkt->getSize() > pkt->getAddr()) {
99955SN/A                return mshr;
100955SN/A            }
1012632Sstever@eecs.umich.edu        } else {
1022632Sstever@eecs.umich.edu            if (pkt->getAddr() + pkt->getSize() > mshr->addr) {
1032632Sstever@eecs.umich.edu                return mshr;
1042632Sstever@eecs.umich.edu            }
1052632Sstever@eecs.umich.edu        }
1062632Sstever@eecs.umich.edu
1072632Sstever@eecs.umich.edu        //need to check destination address for copies.
1082632Sstever@eecs.umich.edu        //TEMP NOT DOING COPIES
1092632Sstever@eecs.umich.edu#if 0
1102632Sstever@eecs.umich.edu        if (mshr->pkt->cmd == Copy) {
1112632Sstever@eecs.umich.edu            Addr dest = mshr->pkt->dest;
1122632Sstever@eecs.umich.edu            if (dest < pkt->addr) {
1132632Sstever@eecs.umich.edu                if (dest + mshr->pkt->size > pkt->addr) {
1142632Sstever@eecs.umich.edu                    return mshr;
1152632Sstever@eecs.umich.edu                }
1162632Sstever@eecs.umich.edu            } else {
1172632Sstever@eecs.umich.edu                if (pkt->addr + pkt->size > dest) {
1182634Sstever@eecs.umich.edu                    return mshr;
1192634Sstever@eecs.umich.edu                }
1202632Sstever@eecs.umich.edu            }
1212638Sstever@eecs.umich.edu        }
1222632Sstever@eecs.umich.edu#endif
1232632Sstever@eecs.umich.edu    }
1242632Sstever@eecs.umich.edu    return NULL;
1252632Sstever@eecs.umich.edu}
1262632Sstever@eecs.umich.edu
1272632Sstever@eecs.umich.eduMSHR*
1281858SN/AMSHRQueue::allocate(Packet * &pkt, int size)
1292638Sstever@eecs.umich.edu{
1302638Sstever@eecs.umich.edu    Addr aligned_addr = pkt->getAddr() & ~((Addr)size - 1);
1312638Sstever@eecs.umich.edu    assert(!freeList.empty());
1322638Sstever@eecs.umich.edu    MSHR *mshr = freeList.front();
1332638Sstever@eecs.umich.edu    assert(mshr->getNumTargets() == 0);
1342638Sstever@eecs.umich.edu    freeList.pop_front();
1352638Sstever@eecs.umich.edu
1362638Sstever@eecs.umich.edu    if (!pkt->needsResponse()) {
1372634Sstever@eecs.umich.edu        mshr->allocateAsBuffer(pkt);
1382634Sstever@eecs.umich.edu    } else {
1392634Sstever@eecs.umich.edu        assert(size !=0);
140955SN/A        mshr->allocate(pkt->cmd, aligned_addr, size, pkt);
141955SN/A        allocatedTargets += 1;
142955SN/A    }
143955SN/A    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
144955SN/A    mshr->readyIter = pendingList.insert(pendingList.end(), mshr);
145955SN/A
146955SN/A    allocated += 1;
147955SN/A    return mshr;
1481858SN/A}
1491858SN/A
1502632Sstever@eecs.umich.eduMSHR*
151955SN/AMSHRQueue::allocateFetch(Addr addr, int size, Packet * &target)
1521858SN/A{
1531105SN/A    MSHR *mshr = freeList.front();
1541869SN/A    assert(mshr->getNumTargets() == 0);
1551869SN/A    freeList.pop_front();
1561869SN/A    mshr->allocate(Packet::ReadReq, addr, size, target);
1571869SN/A    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
1581869SN/A    mshr->readyIter = pendingList.insert(pendingList.end(), mshr);
1591065SN/A
1602632Sstever@eecs.umich.edu    allocated += 1;
1612632Sstever@eecs.umich.edu    return mshr;
162955SN/A}
1631858SN/A
1641858SN/AMSHR*
1651858SN/AMSHRQueue::allocateTargetList(Addr addr, int size)
1661858SN/A{
1671851SN/A    MSHR *mshr = freeList.front();
1681851SN/A    assert(mshr->getNumTargets() == 0);
1691858SN/A    freeList.pop_front();
1702632Sstever@eecs.umich.edu    Packet * dummy;
171955SN/A    mshr->allocate(Packet::ReadReq, addr, size, dummy);
1721858SN/A    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
1731858SN/A    mshr->inService = true;
1741858SN/A    ++inServiceMSHRs;
1752638Sstever@eecs.umich.edu    ++allocated;
1762638Sstever@eecs.umich.edu    return mshr;
1772638Sstever@eecs.umich.edu}
1782638Sstever@eecs.umich.edu
1792638Sstever@eecs.umich.edu
1801858SN/Avoid
1811858SN/AMSHRQueue::deallocate(MSHR* mshr)
1821858SN/A{
1831858SN/A    deallocateOne(mshr);
1841858SN/A}
1851858SN/A
1861858SN/AMSHR::Iterator
1871859SN/AMSHRQueue::deallocateOne(MSHR* mshr)
1881858SN/A{
1891858SN/A    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
1901858SN/A    freeList.push_front(mshr);
1911859SN/A    allocated--;
1921859SN/A    allocatedTargets -= mshr->getNumTargets();
1931862SN/A    if (mshr->inService) {
1941862SN/A        inServiceMSHRs--;
1951862SN/A    } else {
1961862SN/A        pendingList.erase(mshr->readyIter);
1971859SN/A    }
1981859SN/A    mshr->deallocate();
1991963SN/A    return retval;
2001963SN/A}
2011859SN/A
2021859SN/Avoid
2031859SN/AMSHRQueue::moveToFront(MSHR *mshr)
2041859SN/A{
2051859SN/A    if (!mshr->inService) {
2061859SN/A        assert(mshr == *(mshr->readyIter));
2071859SN/A        pendingList.erase(mshr->readyIter);
2081859SN/A        mshr->readyIter = pendingList.insert(pendingList.begin(), mshr);
2091862SN/A    }
2101859SN/A}
2111859SN/A
2121859SN/Avoid
2131858SN/AMSHRQueue::markInService(MSHR* mshr)
2141858SN/A{
2152139SN/A    //assert(mshr == pendingList.front());
2162139SN/A    if (!mshr->pkt->needsResponse()) {
2172139SN/A        assert(mshr->getNumTargets() == 0);
2182155SN/A        deallocate(mshr);
2192623SN/A        return;
2202637Sstever@eecs.umich.edu    }
2212155SN/A    mshr->inService = true;
2221869SN/A    pendingList.erase(mshr->readyIter);
2231869SN/A    //mshr->readyIter = NULL;
2241869SN/A    inServiceMSHRs += 1;
2251869SN/A    //pendingList.pop_front();
2261869SN/A}
2272139SN/A
2281869SN/Avoid
2292508SN/AMSHRQueue::markPending(MSHR* mshr, Packet::Command cmd)
2302508SN/A{
2312508SN/A    //assert(mshr->readyIter == NULL);
2322508SN/A    mshr->pkt->cmd = cmd;
2332635Sstever@eecs.umich.edu    mshr->pkt->flags &= ~SATISFIED;
2342635Sstever@eecs.umich.edu    mshr->inService = false;
2351869SN/A    --inServiceMSHRs;
2361869SN/A    /**
2371869SN/A     * @ todo might want to add rerequests to front of pending list for
2381869SN/A     * performance.
2391869SN/A     */
2401869SN/A    mshr->readyIter = pendingList.insert(pendingList.end(), mshr);
2411869SN/A}
2421869SN/A
2431965SN/Avoid
2441965SN/AMSHRQueue::squash(int threadNum)
2451965SN/A{
2461869SN/A    MSHR::Iterator i = allocatedList.begin();
2471869SN/A    MSHR::Iterator end = allocatedList.end();
2481869SN/A    for (; i != end;) {
2491869SN/A        MSHR *mshr = *i;
2501884SN/A        if (mshr->threadNum == threadNum) {
2511884SN/A            while (mshr->hasTargets()) {
2521884SN/A                Packet * target = mshr->getTarget();
2531869SN/A                mshr->popTarget();
2541858SN/A
2551869SN/A                assert(0/*target->req->getThreadNum()*/ == threadNum);
2561869SN/A                target = NULL;
2571869SN/A            }
2581869SN/A            assert(!mshr->hasTargets());
2591869SN/A            assert(mshr->ntargets==0);
2601858SN/A            if (!mshr->inService) {
2611869SN/A                i = deallocateOne(mshr);
2621869SN/A            } else {
2631869SN/A                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
2641869SN/A                ++i;
2651869SN/A            }
2661869SN/A        } else {
2671869SN/A            ++i;
2681869SN/A        }
2691869SN/A    }
2701869SN/A}
2711858SN/A