mshr_queue.cc revision 4920
12SN/A/*
21762SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Erik Hallnor
292665Ssaidi@eecs.umich.edu */
302SN/A
312SN/A/** @file
322SN/A * Definition of MSHRQueue class functions.
332SN/A */
342SN/A
352520SN/A#include "mem/cache/miss/mshr_queue.hh"
362207SN/A
372207SN/Ausing namespace std;
3811389Sbrandon.potter@amd.com
396214Snate@binkert.orgMSHRQueue::MSHRQueue(int num_entries, int reserve, int _index)
402SN/A    : numEntries(num_entries + reserve - 1), numReserve(reserve),
418706Sandreas.hansson@arm.com      index(_index)
422SN/A{
432SN/A    allocated = 0;
442SN/A    inServiceEntries = 0;
452SN/A    registers = new MSHR[numEntries];
46360SN/A    for (int i = 0; i < numEntries; ++i) {
47360SN/A        registers[i].queue = this;
48360SN/A        freeList.push_back(&registers[i]);
49360SN/A    }
502207SN/A}
514111Sgblack@eecs.umich.edu
524111Sgblack@eecs.umich.eduMSHRQueue::~MSHRQueue()
534155Sgblack@eecs.umich.edu{
545874Sgblack@eecs.umich.edu    delete [] registers;
555874Sgblack@eecs.umich.edu}
5610037SARM gem5 Developers
576691Stjones1@inf.ed.ac.ukMSHR *
587095Sgblack@eecs.umich.eduMSHRQueue::findMatch(Addr addr) const
596691Stjones1@inf.ed.ac.uk{
60360SN/A    MSHR::ConstIterator i = allocatedList.begin();
61360SN/A    MSHR::ConstIterator end = allocatedList.end();
62360SN/A    for (; i != end; ++i) {
63360SN/A        MSHR *mshr = *i;
64360SN/A        if (mshr->addr == addr) {
652207SN/A            return mshr;
666392Ssaidi@eecs.umich.edu        }
6710810Sbr@bsdpad.com    }
6810810Sbr@bsdpad.com    return NULL;
69360SN/A}
70360SN/A
712SN/Abool
7212SN/AMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
7312SN/A{
742SN/A    // Need an empty vector
752SN/A    assert(matches.empty());
76360SN/A    bool retval = false;
77360SN/A    MSHR::ConstIterator i = allocatedList.begin();
78360SN/A    MSHR::ConstIterator end = allocatedList.end();
7910880SCurtis.Dunham@arm.com    for (; i != end; ++i) {
80360SN/A        MSHR *mshr = *i;
8112SN/A        if (mshr->addr == addr) {
822SN/A            retval = true;
832SN/A            matches.push_back(mshr);
842SN/A        }
8511392Sbrandon.potter@amd.com    }
8611392Sbrandon.potter@amd.com    return retval;
8711392Sbrandon.potter@amd.com}
8811392Sbrandon.potter@amd.com
8911392Sbrandon.potter@amd.com
9011392Sbrandon.potter@amd.combool
9111392Sbrandon.potter@amd.comMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
9211392Sbrandon.potter@amd.com{
9311392Sbrandon.potter@amd.com    MSHR::ConstIterator i = allocatedList.begin();
9411392Sbrandon.potter@amd.com    MSHR::ConstIterator end = allocatedList.end();
9511392Sbrandon.potter@amd.com    for (; i != end; ++i) {
9611392Sbrandon.potter@amd.com        MSHR *mshr = *i;
9711392Sbrandon.potter@amd.com        if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) {
989641Sguodeyuan@tsinghua.org.cn            return true;
992SN/A        }
10011389Sbrandon.potter@amd.com    }
10111389Sbrandon.potter@amd.com    return false;
10211389Sbrandon.potter@amd.com}
10311389Sbrandon.potter@amd.com
10411389Sbrandon.potter@amd.com
10511389Sbrandon.potter@amd.comMSHR *
10611389Sbrandon.potter@amd.comMSHRQueue::findPending(Addr addr, int size) const
10711389Sbrandon.potter@amd.com{
1085070Ssaidi@eecs.umich.edu    MSHR::ConstIterator i = readyList.begin();
1093917Ssaidi@eecs.umich.edu    MSHR::ConstIterator end = readyList.end();
110360SN/A    for (; i != end; ++i) {
111360SN/A        MSHR *mshr = *i;
112360SN/A        if (mshr->addr < addr) {
1132SN/A            if (mshr->addr + mshr->size > addr) {
1142SN/A                return mshr;
11512SN/A            }
1162420SN/A        } else {
1172420SN/A            if (addr + size > mshr->addr) {
1182420SN/A                return mshr;
11912SN/A            }
12012SN/A        }
12112SN/A    }
12212SN/A    return NULL;
12312SN/A}
12412SN/A
12512SN/A
12612SN/AMSHR::Iterator
1272SN/AMSHRQueue::addToReadyList(MSHR *mshr)
12811392Sbrandon.potter@amd.com{
12910037SARM gem5 Developers    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
1302472SN/A        return readyList.insert(readyList.end(), mshr);
1312420SN/A    }
1322SN/A
13312SN/A    MSHR::Iterator i = readyList.begin();
1342472SN/A    MSHR::Iterator end = readyList.end();
13512SN/A    for (; i != end; ++i) {
1362SN/A        if ((*i)->readyTime > mshr->readyTime) {
13712SN/A            return readyList.insert(i, mshr);
13812SN/A        }
13912SN/A    }
14012SN/A    assert(false);
14112SN/A    return end;  // keep stupid compilers happy
14212SN/A}
14312SN/A
1443584Ssaidi@eecs.umich.edu
1459261Sdam.sunwoo@arm.comMSHR *
1469261Sdam.sunwoo@arm.comMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
1479261Sdam.sunwoo@arm.com                    Tick when, Counter order)
1489261Sdam.sunwoo@arm.com{
1499261Sdam.sunwoo@arm.com    assert(!freeList.empty());
1503584Ssaidi@eecs.umich.edu    MSHR *mshr = freeList.front();
1512SN/A    assert(mshr->getNumTargets() == 0);
1522SN/A    freeList.pop_front();
1533584Ssaidi@eecs.umich.edu
1542SN/A    mshr->allocate(addr, size, pkt, when, order);
1552SN/A    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
1562SN/A    mshr->readyIter = addToReadyList(mshr);
157
158    allocated += 1;
159    return mshr;
160}
161
162
163void
164MSHRQueue::deallocate(MSHR *mshr)
165{
166    deallocateOne(mshr);
167}
168
169MSHR::Iterator
170MSHRQueue::deallocateOne(MSHR *mshr)
171{
172    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
173    freeList.push_front(mshr);
174    allocated--;
175    if (mshr->inService) {
176        inServiceEntries--;
177    } else {
178        readyList.erase(mshr->readyIter);
179    }
180    mshr->deallocate();
181    return retval;
182}
183
184void
185MSHRQueue::moveToFront(MSHR *mshr)
186{
187    if (!mshr->inService) {
188        assert(mshr == *(mshr->readyIter));
189        readyList.erase(mshr->readyIter);
190        mshr->readyIter = readyList.insert(readyList.begin(), mshr);
191    }
192}
193
194void
195MSHRQueue::markInService(MSHR *mshr)
196{
197    if (mshr->markInService()) {
198        deallocate(mshr);
199    } else {
200        readyList.erase(mshr->readyIter);
201        inServiceEntries += 1;
202    }
203}
204
205void
206MSHRQueue::markPending(MSHR *mshr)
207{
208    assert(mshr->inService);
209    mshr->inService = false;
210    --inServiceEntries;
211    /**
212     * @ todo might want to add rerequests to front of pending list for
213     * performance.
214     */
215    mshr->readyIter = addToReadyList(mshr);
216}
217
218void
219MSHRQueue::squash(int threadNum)
220{
221    MSHR::Iterator i = allocatedList.begin();
222    MSHR::Iterator end = allocatedList.end();
223    for (; i != end;) {
224        MSHR *mshr = *i;
225        if (mshr->threadNum == threadNum) {
226            while (mshr->hasTargets()) {
227                mshr->popTarget();
228                assert(0/*target->req->getThreadNum()*/ == threadNum);
229            }
230            assert(!mshr->hasTargets());
231            assert(mshr->ntargets==0);
232            if (!mshr->inService) {
233                i = deallocateOne(mshr);
234            } else {
235                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
236                ++i;
237            }
238        } else {
239            ++i;
240        }
241    }
242}
243