mem-cache: Avoid hiding a virtual method in the dictionary compressor.
[gem5.git] / src / mem / cache / mshr_queue.cc
index 3736c9f21760709e9602c2c5a4e4b308cf836f38..f4b80540c78a7677b69e84c5a8709e39dd3c32ab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, 2015 ARM Limited
+ * Copyright (c) 2012-2013, 2015-2016, 2018 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 demand_reserve,
-                     int _index)
-    : label(_label), numEntries(num_entries + reserve - 1),
-      numReserve(reserve), demandReserve(demand_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 blk_addr, bool is_secure) const
-{
-    for (const auto& mshr : allocatedList) {
-        // we ignore any MSHRs allocated for uncacheable accesses and
-        // simply ignore them when matching, in the cache we never
-        // check for matches when adding new uncacheable entries, and
-        // we do not want normal cacheable accesses being added to an
-        // MSHR serving an uncacheable access
-        if (!mshr->isUncacheable() && mshr->blkAddr == blk_addr &&
-            mshr->isSecure == is_secure) {
-            return mshr;
-        }
-    }
-    return NULL;
-}
-
-bool
-MSHRQueue::findMatches(Addr blk_addr, bool is_secure,
-                       vector<MSHR*>& matches) const
-{
-    // Need an empty vector
-    assert(matches.empty());
-    bool retval = false;
-    for (const auto& mshr : allocatedList) {
-        if (!mshr->isUncacheable() && mshr->blkAddr == blk_addr &&
-            mshr->isSecure == is_secure) {
-            retval = true;
-            matches.push_back(mshr);
-        }
-    }
-    return retval;
-}
-
-
-bool
-MSHRQueue::checkFunctional(PacketPtr pkt, Addr blk_addr)
-{
-    pkt->pushLabel(label);
-    for (const auto& mshr : allocatedList) {
-        if (mshr->blkAddr == blk_addr && mshr->checkFunctional(pkt)) {
-            pkt->popLabel();
-            return true;
-        }
-    }
-    pkt->popLabel();
-    return false;
-}
-
-
-MSHR *
-MSHRQueue::findPending(Addr blk_addr, bool is_secure) const
-{
-    for (const auto& mshr : readyList) {
-        if (mshr->blkAddr == blk_addr && mshr->isSecure == is_secure) {
-            return mshr;
-        }
-    }
-    return NULL;
-}
-
-
-MSHR::Iterator
-MSHRQueue::addToReadyList(MSHR *mshr)
-{
-    if (readyList.empty() || readyList.back()->readyTime <= mshr->readyTime) {
-        return readyList.insert(readyList.end(), mshr);
-    }
-
-    for (auto i = readyList.begin(); i != readyList.end(); ++i) {
-        if ((*i)->readyTime > mshr->readyTime) {
-            return readyList.insert(i, mshr);
-        }
-    }
-    assert(false);
-    return readyList.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 blk_addr, unsigned blk_size, PacketPtr pkt,
-                    Tick when_ready, Counter order)
+                    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(blk_addr, blk_size, pkt, when_ready, 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);
 
@@ -161,36 +74,6 @@ MSHRQueue::allocate(Addr blk_addr, unsigned blk_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(DrainState::Drained);
-    }
-    return retval;
-}
-
 void
 MSHRQueue::moveToFront(MSHR *mshr)
 {
@@ -202,14 +85,22 @@ MSHRQueue::moveToFront(MSHR *mshr)
 }
 
 void
-MSHRQueue::markInService(MSHR *mshr, bool pending_dirty_resp)
+MSHRQueue::delay(MSHR *mshr, Tick delay_ticks)
 {
-    if (mshr->markInService(pending_dirty_resp)) {
-        deallocate(mshr);
-    } else {
-        readyList.erase(mshr->readyIter);
-        inServiceEntries += 1;
-    }
+    mshr->delay(delay_ticks);
+    auto it = std::find_if(mshr->readyIter, readyList.end(),
+                            [mshr] (const MSHR* _mshr) {
+                                return mshr->readyTime >= _mshr->readyTime;
+                            });
+    readyList.splice(it, readyList, mshr->readyIter);
+}
+
+void
+MSHRQueue::markInService(MSHR *mshr, bool pending_modified_resp)
+{
+    mshr->markInService(pending_modified_resp);
+    readyList.erase(mshr->readyIter);
+    _numInService += 1;
 }
 
 void
@@ -217,7 +108,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.
@@ -234,46 +125,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)
-{
-    for (auto i = allocatedList.begin(); i != allocatedList.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(DrainState::Drained);
-        return 0;
-    } else {
-        drainManager = dm;
-        setDrainState(DrainState::Draining);
-        return 1;
-    }
-}