Ruby: remove reference to g_system_ptr from class Message
[gem5.git] / src / mem / simple_dram.cc
index 3dc59e8e0e5e12b80035c43564014a216c78dedc..62825d13905e93189a7c06e8f37b3faa9f1798ed 100644 (file)
@@ -38,6 +38,8 @@
  *          Ani Udipi
  */
 
+#include "base/trace.hh"
+#include "debug/Drain.hh"
 #include "debug/DRAM.hh"
 #include "debug/DRAMWR.hh"
 #include "mem/simple_dram.hh"
@@ -934,15 +936,18 @@ SimpleDRAM::scheduleNextReq()
     DPRINTF(DRAM, "Reached scheduleNextReq()\n");
 
     // Figure out which request goes next, and move it to front()
-    if (!chooseNextReq())
-        return;
-
-    doDRAMAccess(dramReadQueue.front());
+    if (!chooseNextReq()) {
+        // In the case there is no read request to go next, see if we
+        // are asked to drain, and if so trigger writes, this also
+        // ensures that if we hit the write limit we will do this
+        // multiple times until we are completely drained
+        if (drainManager && !dramWriteQueue.empty() && !writeEvent.scheduled())
+            triggerWrites();
+    } else {
+        doDRAMAccess(dramReadQueue.front());
+    }
 }
 
-
-
-
 Tick
 SimpleDRAM::maxBankFreeAt() const
 {
@@ -1212,8 +1217,18 @@ SimpleDRAM::drain(DrainManager *dm)
     // of that as well
     if (!(dramWriteQueue.empty() && dramReadQueue.empty() &&
           dramRespQueue.empty())) {
+        DPRINTF(Drain, "DRAM controller not drained, write: %d, read: %d,"
+                " resp: %d\n", dramWriteQueue.size(), dramReadQueue.size(),
+                dramRespQueue.size());
         ++count;
         drainManager = dm;
+        // the only part that is not drained automatically over time
+        // is the write queue, thus trigger writes if there are any
+        // waiting and no reads waiting, otherwise wait until the
+        // reads are done
+        if (dramReadQueue.empty() && !dramWriteQueue.empty() &&
+            !writeEvent.scheduled())
+            triggerWrites();
     }
 
     if (count)