mem-cache: Fix non-bijective function in Skewed caches
[gem5.git] / src / mem / cache / mshr_queue.cc
index 9146cddf73a654fb1eec8965aa0621592c59a365..e44a21954b50299b8548499cb7cd7480f24d7c7c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013 ARM Limited
+ * Copyright (c) 2012-2013, 2015-2016 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
  * Definition of MSHRQueue class functions.
  */
 
-#include "base/trace.hh"
 #include "mem/cache/mshr_queue.hh"
-#include "debug/Drain.hh"
 
-using namespace std;
+#include <cassert>
 
-MSHRQueue::MSHRQueue(const std::string &_label,
-                     int num_entries, int reserve, int _index)
-    : label(_label), numEntries(num_entries + reserve - 1),
-      numReserve(reserve), registers(numEntries),
-      drainManager(NULL), allocated(0), inServiceEntries(0), index(_index)
-{
-    for (int i = 0; i < numEntries; ++i) {
-        registers[i].queue = this;
-        freeList.push_back(&registers[i]);
-    }
-}
-
-MSHR *
-MSHRQueue::findMatch(Addr addr, bool is_secure) const
-{
-    MSHR::ConstIterator i = allocatedList.begin();
-    MSHR::ConstIterator end = allocatedList.end();
-    for (; i != end; ++i) {
-        MSHR *mshr = *i;
-        if (mshr->addr == addr && mshr->isSecure == is_secure) {
-            return mshr;
-        }
-    }
-    return NULL;
-}
-
-bool
-MSHRQueue::findMatches(Addr addr, bool is_secure, vector<MSHR*>& matches) const
-{
-    // Need an empty vector
-    assert(matches.empty());
-    bool retval = false;
-    MSHR::ConstIterator i = allocatedList.begin();
-    MSHR::ConstIterator end = allocatedList.end();
-    for (; i != end; ++i) {
-        MSHR *mshr = *i;
-        if (mshr->addr == addr && mshr->isSecure == is_secure) {
-            retval = true;
-            matches.push_back(mshr);
-        }
-    }
-    return retval;
-}
-
-
-bool
-MSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
-{
-    pkt->pushLabel(label);
-    MSHR::ConstIterator i = allocatedList.begin();
-    MSHR::ConstIterator end = allocatedList.end();
-    for (; i != end; ++i) {
-        MSHR *mshr = *i;
-        if (mshr->addr == blk_addr && mshr->checkFunctional(pkt)) {
-            pkt->popLabel();
-            return true;
-        }
-    }
-    pkt->popLabel();
-    return false;
-}
-
-
-MSHR *
-MSHRQueue::findPending(Addr addr, int size, bool is_secure) const
-{
-    MSHR::ConstIterator i = readyList.begin();
-    MSHR::ConstIterator end = readyList.end();
-    for (; i != end; ++i) {
-        MSHR *mshr = *i;
-        if (mshr->isSecure == is_secure) {
-            if (mshr->addr < addr) {
-                if (mshr->addr + mshr->size > addr)
-                    return mshr;
-            } else {
-                if (addr + size > mshr->addr)
-                    return mshr;
-            }
-        }
-    }
-    return NULL;
-}
-
-
-MSHR::Iterator
-MSHRQueue::addToReadyList(MSHR *mshr)
-{
-    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
-        return readyList.insert(readyList.end(), mshr);
-    }
-
-    MSHR::Iterator i = readyList.begin();
-    MSHR::Iterator end = readyList.end();
-    for (; i != end; ++i) {
-        if ((*i)->readyTime > mshr->readyTime) {
-            return readyList.insert(i, mshr);
-        }
-    }
-    assert(false);
-    return end;  // keep stupid compilers happy
-}
+#include "mem/cache/mshr.hh"
 
+MSHRQueue::MSHRQueue(const std::string &_label,
+                     int num_entries, int reserve, int demand_reserve)
+    : Queue<MSHR>(_label, num_entries, reserve),
+      demandReserve(demand_reserve)
+{}
 
 MSHR *
-MSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
-                    Tick when, Counter order)
+MSHRQueue::allocate(Addr blk_addr, unsigned blk_size, PacketPtr pkt,
+                    Tick when_ready, Counter order, bool alloc_on_fill)
 {
     assert(!freeList.empty());
     MSHR *mshr = freeList.front();
     assert(mshr->getNumTargets() == 0);
     freeList.pop_front();
 
-    mshr->allocate(addr, size, pkt, when, order);
+    mshr->allocate(blk_addr, blk_size, pkt, when_ready, order, alloc_on_fill);
     mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
     mshr->readyIter = addToReadyList(mshr);
 
@@ -171,36 +74,6 @@ MSHRQueue::allocate(Addr addr, int size, PacketPtr &pkt,
     return mshr;
 }
 
-
-void
-MSHRQueue::deallocate(MSHR *mshr)
-{
-    deallocateOne(mshr);
-}
-
-MSHR::Iterator
-MSHRQueue::deallocateOne(MSHR *mshr)
-{
-    MSHR::Iterator retval = allocatedList.erase(mshr->allocIter);
-    freeList.push_front(mshr);
-    allocated--;
-    if (mshr->inService) {
-        inServiceEntries--;
-    } else {
-        readyList.erase(mshr->readyIter);
-    }
-    mshr->deallocate();
-    if (drainManager && allocated == 0) {
-        // Notify the drain manager that we have completed draining if
-        // there are no other outstanding requests in this MSHR queue.
-        DPRINTF(Drain, "MSHRQueue now empty, signalling drained\n");
-        drainManager->signalDrainDone();
-        drainManager = NULL;
-        setDrainState(Drainable::Drained);
-    }
-    return retval;
-}
-
 void
 MSHRQueue::moveToFront(MSHR *mshr)
 {
@@ -212,14 +85,11 @@ MSHRQueue::moveToFront(MSHR *mshr)
 }
 
 void
-MSHRQueue::markInService(MSHR *mshr, PacketPtr pkt)
+MSHRQueue::markInService(MSHR *mshr, bool pending_modified_resp)
 {
-    if (mshr->markInService(pkt)) {
-        deallocate(mshr);
-    } else {
-        readyList.erase(mshr->readyIter);
-        inServiceEntries += 1;
-    }
+    mshr->markInService(pending_modified_resp);
+    readyList.erase(mshr->readyIter);
+    _numInService += 1;
 }
 
 void
@@ -227,7 +97,7 @@ MSHRQueue::markPending(MSHR *mshr)
 {
     assert(mshr->inService);
     mshr->inService = false;
-    --inServiceEntries;
+    --_numInService;
     /**
      * @ todo might want to add rerequests to front of pending list for
      * performance.
@@ -244,48 +114,9 @@ MSHRQueue::forceDeallocateTarget(MSHR *mshr)
     mshr->popTarget();
     // Delete mshr if no remaining targets
     if (!mshr->hasTargets() && !mshr->promoteDeferredTargets()) {
-        deallocateOne(mshr);
+        deallocate(mshr);
     }
 
     // Notify if MSHR queue no longer full
     return was_full && !isFull();
 }
-
-void
-MSHRQueue::squash(int threadNum)
-{
-    MSHR::Iterator i = allocatedList.begin();
-    MSHR::Iterator end = allocatedList.end();
-    for (; i != end;) {
-        MSHR *mshr = *i;
-        if (mshr->threadNum == threadNum) {
-            while (mshr->hasTargets()) {
-                mshr->popTarget();
-                assert(0/*target->req->threadId()*/ == threadNum);
-            }
-            assert(!mshr->hasTargets());
-            assert(mshr->getNumTargets()==0);
-            if (!mshr->inService) {
-                i = deallocateOne(mshr);
-            } else {
-                //mshr->pkt->flags &= ~CACHE_LINE_FILL;
-                ++i;
-            }
-        } else {
-            ++i;
-        }
-    }
-}
-
-unsigned int
-MSHRQueue::drain(DrainManager *dm)
-{
-    if (allocated == 0) {
-        setDrainState(Drainable::Drained);
-        return 0;
-    } else {
-        drainManager = dm;
-        setDrainState(Drainable::Draining);
-        return 1;
-    }
-}