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.
272665SN/A *
282665SN/A * Authors: Erik Hallnor
292SN/A */
302SN/A
312SN/A/** @file
322SN/A * Definition of MSHRQueue class functions.
336214Snate@binkert.org */
342SN/A
352SN/A#include "mem/cache/miss/mshr_queue.hh"
362SN/A
376214Snate@binkert.orgusing namespace std;
386214Snate@binkert.org
392SN/AMSHRQueue::MSHRQueue(int num_entries, int reserve, int _index)
402SN/A    : numEntries(num_entries + reserve - 1), numReserve(reserve),
412SN/A      index(_index)
429180Sandreas.hansson@arm.com{
4310474Sandreas.hansson@arm.com    allocated = 0;
449500Snilay@cs.wisc.edu    inServiceEntries = 0;
4511004SAndreas.Sandberg@ARM.com    registers = new MSHR[numEntries];
469180Sandreas.hansson@arm.com    for (int i = 0; i < numEntries; ++i) {
4710276SAndreas.Sandberg@ARM.com        registers[i].queue = this;
4810276SAndreas.Sandberg@ARM.com        freeList.push_back(&registers[i]);
492SN/A    }
505543SN/A}
512SN/A
525543SN/AMSHRQueue::~MSHRQueue()
532SN/A{
542SN/A    delete [] registers;
552SN/A}
562SN/A
572SN/AMSHR *
582SN/AMSHRQueue::findMatch(Addr addr) const
592SN/A{
602SN/A    MSHR::ConstIterator i = allocatedList.begin();
619158Sandreas.hansson@arm.com    MSHR::ConstIterator end = allocatedList.end();
622SN/A    for (; i != end; ++i) {
639158Sandreas.hansson@arm.com        MSHR *mshr = *i;
642SN/A        if (mshr->addr == addr) {
659158Sandreas.hansson@arm.com            return mshr;
662667SN/A        }
672130SN/A    }
689180Sandreas.hansson@arm.com    return NULL;
699180Sandreas.hansson@arm.com}
709180Sandreas.hansson@arm.com
719180Sandreas.hansson@arm.combool
729180Sandreas.hansson@arm.comMSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
739180Sandreas.hansson@arm.com{
749180Sandreas.hansson@arm.com    // Need an empty vector
759180Sandreas.hansson@arm.com    assert(matches.empty());
7611990Sandreas.sandberg@arm.com    bool retval = false;
779180Sandreas.hansson@arm.com    MSHR::ConstIterator i = allocatedList.begin();
789180Sandreas.hansson@arm.com    MSHR::ConstIterator end = allocatedList.end();
799180Sandreas.hansson@arm.com    for (; i != end; ++i) {
809180Sandreas.hansson@arm.com        MSHR *mshr = *i;
819180Sandreas.hansson@arm.com        if (mshr->addr == addr) {
829180Sandreas.hansson@arm.com            retval = true;
839180Sandreas.hansson@arm.com            matches.push_back(mshr);
849180Sandreas.hansson@arm.com        }
859180Sandreas.hansson@arm.com    }
869180Sandreas.hansson@arm.com    return retval;
879180Sandreas.hansson@arm.com}
889180Sandreas.hansson@arm.com
899180Sandreas.hansson@arm.com
909180Sandreas.hansson@arm.combool
919180Sandreas.hansson@arm.comMSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
929180Sandreas.hansson@arm.com{
939180Sandreas.hansson@arm.com    MSHR::ConstIterator i = allocatedList.begin();
9411004SAndreas.Sandberg@ARM.com    MSHR::ConstIterator end = allocatedList.end();
959180Sandreas.hansson@arm.com    for (; i != end; ++i) {
969184Sandreas.hansson@arm.com        MSHR *mshr = *i;
979184Sandreas.hansson@arm.com        if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) {
989184Sandreas.hansson@arm.com            return true;
999180Sandreas.hansson@arm.com        }
10011004SAndreas.Sandberg@ARM.com    }
1019180Sandreas.hansson@arm.com    return false;
1029180Sandreas.hansson@arm.com}
1039180Sandreas.hansson@arm.com
1049180Sandreas.hansson@arm.com
1059180Sandreas.hansson@arm.comMSHR *
1069180Sandreas.hansson@arm.comMSHRQueue::findPending(Addr addr, int size) const
1079180Sandreas.hansson@arm.com{
1089180Sandreas.hansson@arm.com    MSHR::ConstIterator i = readyList.begin();
1099180Sandreas.hansson@arm.com    MSHR::ConstIterator end = readyList.end();
1109180Sandreas.hansson@arm.com    for (; i != end; ++i) {
11111004SAndreas.Sandberg@ARM.com        MSHR *mshr = *i;
1129180Sandreas.hansson@arm.com        if (mshr->addr < addr) {
1139180Sandreas.hansson@arm.com            if (mshr->addr + mshr->size > addr) {
1149180Sandreas.hansson@arm.com                return mshr;
11511004SAndreas.Sandberg@ARM.com            }
1169180Sandreas.hansson@arm.com        } else {
1179180Sandreas.hansson@arm.com            if (addr + size > mshr->addr) {
11811004SAndreas.Sandberg@ARM.com                return mshr;
1199498Snilay@cs.wisc.edu            }
1209498Snilay@cs.wisc.edu        }
12111004SAndreas.Sandberg@ARM.com    }
12211004SAndreas.Sandberg@ARM.com    return NULL;
12311004SAndreas.Sandberg@ARM.com}
12411004SAndreas.Sandberg@ARM.com
12511004SAndreas.Sandberg@ARM.com
1269498Snilay@cs.wisc.eduMSHR::Iterator
12711004SAndreas.Sandberg@ARM.comMSHRQueue::addToReadyList(MSHR *mshr)
1289498Snilay@cs.wisc.edu{
1299498Snilay@cs.wisc.edu    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
13011004SAndreas.Sandberg@ARM.com        return readyList.insert(readyList.end(), mshr);
1319498Snilay@cs.wisc.edu    }
1329498Snilay@cs.wisc.edu
1339500Snilay@cs.wisc.edu    MSHR::Iterator i = readyList.begin();
1349180Sandreas.hansson@arm.com    MSHR::Iterator end = readyList.end();
1359180Sandreas.hansson@arm.com    for (; i != end; ++i) {
1369180Sandreas.hansson@arm.com        if ((*i)->readyTime > mshr->readyTime) {
1372130SN/A            return readyList.insert(i, mshr);
1382130SN/A        }
1392130SN/A    }
1402130SN/A    assert(false);
1412130SN/A    return end;  // keep stupid compilers happy
1422130SN/A}
1432130SN/A
1447720Sgblack@eecs.umich.edu
1457720Sgblack@eecs.umich.eduMSHR *
1467720Sgblack@eecs.umich.eduMSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
1477720Sgblack@eecs.umich.edu                    Tick when, Counter order)
1487720Sgblack@eecs.umich.edu{
1497720Sgblack@eecs.umich.edu    assert(!freeList.empty());
1507720Sgblack@eecs.umich.edu    MSHR *mshr = freeList.front();
1517720Sgblack@eecs.umich.edu    assert(mshr->getNumTargets() == 0);
1527720Sgblack@eecs.umich.edu    freeList.pop_front();
1537720Sgblack@eecs.umich.edu
1547720Sgblack@eecs.umich.edu    mshr->allocate(addr, size, pkt, when, order);
1557720Sgblack@eecs.umich.edu    mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
1567720Sgblack@eecs.umich.edu    mshr->readyIter = addToReadyList(mshr);
1577720Sgblack@eecs.umich.edu
1587720Sgblack@eecs.umich.edu    allocated += 1;
1597720Sgblack@eecs.umich.edu    return mshr;
1607720Sgblack@eecs.umich.edu}
1617720Sgblack@eecs.umich.edu
1627720Sgblack@eecs.umich.edu
1637720Sgblack@eecs.umich.eduvoid
1647720Sgblack@eecs.umich.eduMSHRQueue::deallocate(MSHR *mshr)
1657720Sgblack@eecs.umich.edu{
1662438SN/A    deallocateOne(mshr);
1672438SN/A}
1686221Snate@binkert.org
1696221Snate@binkert.orgMSHR::Iterator
1706221Snate@binkert.orgMSHRQueue::deallocateOne(MSHR *mshr)
1716221Snate@binkert.org{
1726221Snate@binkert.org    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
1736221Snate@binkert.org    freeList.push_front(mshr);
17411005Sandreas.sandberg@arm.com    allocated--;
17511005Sandreas.sandberg@arm.com    if (mshr->inService) {
17611005Sandreas.sandberg@arm.com        inServiceEntries--;
17711005Sandreas.sandberg@arm.com    } else {
1789031Sandreas.hansson@arm.com        readyList.erase(mshr->readyIter);
1799031Sandreas.hansson@arm.com    }
1809031Sandreas.hansson@arm.com    mshr->deallocate();
1819031Sandreas.hansson@arm.com    return retval;
1829031Sandreas.hansson@arm.com}
1839031Sandreas.hansson@arm.com
1847678Sgblack@eecs.umich.eduvoid
18510474Sandreas.hansson@arm.comMSHRQueue::moveToFront(MSHR *mshr)
18610474Sandreas.hansson@arm.com{
18710474Sandreas.hansson@arm.com    if (!mshr->inService) {
18810474Sandreas.hansson@arm.com        assert(mshr == *(mshr->readyIter));
18910474Sandreas.hansson@arm.com        readyList.erase(mshr->readyIter);
1907678Sgblack@eecs.umich.edu        mshr->readyIter = readyList.insert(readyList.begin(), mshr);
19111306Santhony.gutierrez@amd.com    }
19211306Santhony.gutierrez@amd.com}
19311306Santhony.gutierrez@amd.com
19411306Santhony.gutierrez@amd.comvoid
19511306Santhony.gutierrez@amd.comMSHRQueue::markInService(MSHR *mshr)
19611306Santhony.gutierrez@amd.com{
19711306Santhony.gutierrez@amd.com    if (mshr->markInService()) {
19811306Santhony.gutierrez@amd.com        deallocate(mshr);
19911306Santhony.gutierrez@amd.com    } else {
20011306Santhony.gutierrez@amd.com        readyList.erase(mshr->readyIter);
20111306Santhony.gutierrez@amd.com        inServiceEntries += 1;
20211306Santhony.gutierrez@amd.com    }
20311306Santhony.gutierrez@amd.com}
20410839Sandreas.sandberg@arm.com
20510839Sandreas.sandberg@arm.comvoid
20610839Sandreas.sandberg@arm.comMSHRQueue::markPending(MSHR *mshr)
20710839Sandreas.sandberg@arm.com{
20810839Sandreas.sandberg@arm.com    assert(mshr->inService);
2096214Snate@binkert.org    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