mshr_queue.cc revision 4871
18092Snilay@cs.wisc.edu/*
28092Snilay@cs.wisc.edu * Copyright (c) 2003-2005 The Regents of The University of Michigan
38092Snilay@cs.wisc.edu * All rights reserved.
48092Snilay@cs.wisc.edu *
58092Snilay@cs.wisc.edu * Redistribution and use in source and binary forms, with or without
68092Snilay@cs.wisc.edu * modification, are permitted provided that the following conditions are
78092Snilay@cs.wisc.edu * met: redistributions of source code must retain the above copyright
88092Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer;
98092Snilay@cs.wisc.edu * redistributions in binary form must reproduce the above copyright
108092Snilay@cs.wisc.edu * notice, this list of conditions and the following disclaimer in the
118092Snilay@cs.wisc.edu * documentation and/or other materials provided with the distribution;
128092Snilay@cs.wisc.edu * neither the name of the copyright holders nor the names of its
138092Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from
148092Snilay@cs.wisc.edu * this software without specific prior written permission.
158092Snilay@cs.wisc.edu *
168092Snilay@cs.wisc.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
178092Snilay@cs.wisc.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188092Snilay@cs.wisc.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
198092Snilay@cs.wisc.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
208092Snilay@cs.wisc.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
218092Snilay@cs.wisc.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
228092Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
238092Snilay@cs.wisc.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
248092Snilay@cs.wisc.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258092Snilay@cs.wisc.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
268092Snilay@cs.wisc.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278092Snilay@cs.wisc.edu *
288092Snilay@cs.wisc.edu * Authors: Erik Hallnor
298092Snilay@cs.wisc.edu */
308092Snilay@cs.wisc.edu
318092Snilay@cs.wisc.edu/** @file
328092Snilay@cs.wisc.edu * Definition of MSHRQueue class functions.
338092Snilay@cs.wisc.edu */
348092Snilay@cs.wisc.edu
358164Snilay@cs.wisc.edu#include "mem/cache/miss/mshr_queue.hh"
368165Snilay@cs.wisc.edu
378092Snilay@cs.wisc.eduusing namespace std;
388092Snilay@cs.wisc.edu
398092Snilay@cs.wisc.eduMSHRQueue::MSHRQueue(int num_entries, int reserve, int _index)
408092Snilay@cs.wisc.edu    : numEntries(num_entries + reserve - 1), numReserve(reserve),
418092Snilay@cs.wisc.edu      index(_index)
428092Snilay@cs.wisc.edu{
438174Snilay@cs.wisc.edu    allocated = 0;
448092Snilay@cs.wisc.edu    inServiceEntries = 0;
458092Snilay@cs.wisc.edu    registers = new MSHR[numEntries];
468174Snilay@cs.wisc.edu    for (int i = 0; i < numEntries; ++i) {
478174Snilay@cs.wisc.edu        registers[i].queue = this;
488174Snilay@cs.wisc.edu        freeList.push_back(&registers[i]);
498174Snilay@cs.wisc.edu    }
508174Snilay@cs.wisc.edu}
518174Snilay@cs.wisc.edu
528174Snilay@cs.wisc.eduMSHRQueue::~MSHRQueue()
538092Snilay@cs.wisc.edu{
548092Snilay@cs.wisc.edu    delete [] registers;
558188SLisa.Hsu@amd.com}
568092Snilay@cs.wisc.edu
578092Snilay@cs.wisc.eduMSHR *
588174Snilay@cs.wisc.eduMSHRQueue::findMatch(Addr addr) const
598174Snilay@cs.wisc.edu{
608174Snilay@cs.wisc.edu    MSHR::ConstIterator i = allocatedList.begin();
618174Snilay@cs.wisc.edu    MSHR::ConstIterator end = allocatedList.end();
628174Snilay@cs.wisc.edu    for (; i != end; ++i) {
638174Snilay@cs.wisc.edu        MSHR *mshr = *i;
648174Snilay@cs.wisc.edu        if (mshr->addr == addr) {
658174Snilay@cs.wisc.edu            return mshr;
668174Snilay@cs.wisc.edu        }
678174Snilay@cs.wisc.edu    }
688092Snilay@cs.wisc.edu    return NULL;
698092Snilay@cs.wisc.edu}
708188SLisa.Hsu@amd.com
718174Snilay@cs.wisc.edubool
728174Snilay@cs.wisc.eduMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
738174Snilay@cs.wisc.edu{
748174Snilay@cs.wisc.edu    // Need an empty vector
758174Snilay@cs.wisc.edu    assert(matches.empty());
768174Snilay@cs.wisc.edu    bool retval = false;
778174Snilay@cs.wisc.edu    MSHR::ConstIterator i = allocatedList.begin();
788174Snilay@cs.wisc.edu    MSHR::ConstIterator end = allocatedList.end();
798174Snilay@cs.wisc.edu    for (; i != end; ++i) {
808174Snilay@cs.wisc.edu        MSHR *mshr = *i;
818174Snilay@cs.wisc.edu        if (mshr->addr == addr) {
828174Snilay@cs.wisc.edu            retval = true;
838174Snilay@cs.wisc.edu            matches.push_back(mshr);
848174Snilay@cs.wisc.edu        }
858174Snilay@cs.wisc.edu    }
868174Snilay@cs.wisc.edu    return retval;
878174Snilay@cs.wisc.edu
888174Snilay@cs.wisc.edu}
898174Snilay@cs.wisc.edu
908174Snilay@cs.wisc.eduMSHR *
918174Snilay@cs.wisc.eduMSHRQueue::findPending(Addr addr, int size) const
928174Snilay@cs.wisc.edu{
938174Snilay@cs.wisc.edu    MSHR::ConstIterator i = readyList.begin();
948174Snilay@cs.wisc.edu    MSHR::ConstIterator end = readyList.end();
958174Snilay@cs.wisc.edu    for (; i != end; ++i) {
968174Snilay@cs.wisc.edu        MSHR *mshr = *i;
978174Snilay@cs.wisc.edu        if (mshr->addr < addr) {
988174Snilay@cs.wisc.edu            if (mshr->addr + mshr->size > addr) {
998174Snilay@cs.wisc.edu                return mshr;
1008174Snilay@cs.wisc.edu            }
1018174Snilay@cs.wisc.edu        } else {
1028174Snilay@cs.wisc.edu            if (addr + size > mshr->addr) {
1038174Snilay@cs.wisc.edu                return mshr;
1048174Snilay@cs.wisc.edu            }
1058174Snilay@cs.wisc.edu        }
1068174Snilay@cs.wisc.edu    }
1078174Snilay@cs.wisc.edu    return NULL;
1088174Snilay@cs.wisc.edu}
1098174Snilay@cs.wisc.edu
1108174Snilay@cs.wisc.edu
1118174Snilay@cs.wisc.eduMSHR::Iterator
1128174Snilay@cs.wisc.eduMSHRQueue::addToReadyList(MSHR *mshr)
1138174Snilay@cs.wisc.edu{
1148174Snilay@cs.wisc.edu    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
1158174Snilay@cs.wisc.edu        return readyList.insert(readyList.end(), mshr);
1168174Snilay@cs.wisc.edu    }
1178174Snilay@cs.wisc.edu
1188174Snilay@cs.wisc.edu    MSHR::Iterator i = readyList.begin();
1198174Snilay@cs.wisc.edu    MSHR::Iterator end = readyList.end();
1208174Snilay@cs.wisc.edu    for (; i != end; ++i) {
1218174Snilay@cs.wisc.edu        if ((*i)->readyTime > mshr->readyTime) {
1228174Snilay@cs.wisc.edu            return readyList.insert(i, mshr);
1238174Snilay@cs.wisc.edu        }
1248174Snilay@cs.wisc.edu    }
1258174Snilay@cs.wisc.edu    assert(false);
1268174Snilay@cs.wisc.edu}
1278174Snilay@cs.wisc.edu
1288174Snilay@cs.wisc.edu
1298092Snilay@cs.wisc.eduMSHR *
1308092Snilay@cs.wisc.eduMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
1318092Snilay@cs.wisc.edu                    Tick when, Counter order)
1328092Snilay@cs.wisc.edu{
1338174Snilay@cs.wisc.edu    assert(!freeList.empty());
1348174Snilay@cs.wisc.edu    MSHR *mshr = freeList.front();
1358174Snilay@cs.wisc.edu    assert(mshr->getNumTargets() == 0);
1368174Snilay@cs.wisc.edu    freeList.pop_front();
1378174Snilay@cs.wisc.edu
1388174Snilay@cs.wisc.edu    mshr->allocate(addr, size, pkt, when, order);
1398174Snilay@cs.wisc.edu    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
1408092Snilay@cs.wisc.edu    mshr->readyIter = addToReadyList(mshr);
1418092Snilay@cs.wisc.edu
142    allocated += 1;
143    return mshr;
144}
145
146
147void
148MSHRQueue::deallocate(MSHR *mshr)
149{
150    deallocateOne(mshr);
151}
152
153MSHR::Iterator
154MSHRQueue::deallocateOne(MSHR *mshr)
155{
156    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
157    freeList.push_front(mshr);
158    allocated--;
159    if (mshr->inService) {
160        inServiceEntries--;
161    } else {
162        readyList.erase(mshr->readyIter);
163    }
164    mshr->deallocate();
165    return retval;
166}
167
168void
169MSHRQueue::moveToFront(MSHR *mshr)
170{
171    if (!mshr->inService) {
172        assert(mshr == *(mshr->readyIter));
173        readyList.erase(mshr->readyIter);
174        mshr->readyIter = readyList.insert(readyList.begin(), mshr);
175    }
176}
177
178void
179MSHRQueue::markInService(MSHR *mshr)
180{
181    assert(!mshr->inService);
182    if (mshr->isSimpleForward()) {
183        // we just forwarded the request packet & don't expect a
184        // response, so get rid of it
185        assert(mshr->getNumTargets() == 1);
186        mshr->popTarget();
187        deallocate(mshr);
188        return;
189    }
190    mshr->inService = true;
191    readyList.erase(mshr->readyIter);
192    //mshr->readyIter = NULL;
193    inServiceEntries += 1;
194    //readyList.pop_front();
195}
196
197void
198MSHRQueue::markPending(MSHR *mshr)
199{
200    assert(mshr->inService);
201    mshr->inService = false;
202    --inServiceEntries;
203    /**
204     * @ todo might want to add rerequests to front of pending list for
205     * performance.
206     */
207    mshr->readyIter = addToReadyList(mshr);
208}
209
210void
211MSHRQueue::squash(int threadNum)
212{
213    MSHR::Iterator i = allocatedList.begin();
214    MSHR::Iterator end = allocatedList.end();
215    for (; i != end;) {
216        MSHR *mshr = *i;
217        if (mshr->threadNum == threadNum) {
218            while (mshr->hasTargets()) {
219                mshr->popTarget();
220                assert(0/*target->req->getThreadNum()*/ == threadNum);
221            }
222            assert(!mshr->hasTargets());
223            assert(mshr->ntargets==0);
224            if (!mshr->inService) {
225                i = deallocateOne(mshr);
226            } else {
227                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
228                ++i;
229            }
230        } else {
231            ++i;
232        }
233    }
234}
235