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(®isters[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