Added code to handle draining.
authorGabe Black <gblack@eecs.umich.edu>
Thu, 2 Nov 2006 00:00:49 +0000 (19:00 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Thu, 2 Nov 2006 00:00:49 +0000 (19:00 -0500)
--HG--
extra : convert_revision : 3861f553bde5865cd21a8a58a4c410896726f0a3

src/mem/bus.cc
src/mem/bus.hh

index 86a148f8734239602f6def29fc0d5dddb3b3c532..41dc9acbf72aa66a0f1e6d5e7745047c5b12ac33 100644 (file)
@@ -239,6 +239,9 @@ Bus::recvRetry(int id)
                 busIdle.reschedule(tickNextIdle);
             }
         }
+        //If we weren't able to drain before, we might be able to now.
+        if (drainEvent && retryList.size() == 0 && curTick >= tickNextIdle)
+            drainEvent->process();
     }
 }
 
@@ -498,6 +501,20 @@ Bus::addressRanges(AddrRangeList &resp, AddrRangeList &snoop, int id)
     }
 }
 
+unsigned int
+Bus::drain(Event * de)
+{
+    //We should check that we're not "doing" anything, and that noone is
+    //waiting. We might be idle but have someone waiting if the device we
+    //contacted for a retry didn't actually retry.
+    if (curTick >= tickNextIdle && retryList.size() == 0) {
+        drainEvent = de;
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
 BEGIN_DECLARE_SIM_OBJECT_PARAMS(Bus)
 
     Param<int> bus_id;
index 9fb33b7c385d6e66dc385a1429d9b1cd2defe461..71067032db1036c66bfea488ef93df92c01bc282 100644 (file)
@@ -59,6 +59,8 @@ class Bus : public MemObject
     /** the next tick at which the bus will be idle */
     Tick tickNextIdle;
 
+    Event * drainEvent;
+
     static const int defaultId = -3; //Make it unique from Broadcast
 
     struct DevMap {
@@ -247,6 +249,8 @@ class Bus : public MemObject
 
     virtual void init();
 
+    unsigned int drain(Event *de);
+
     Bus(const std::string &n, int bus_id, int _clock, int _width)
         : MemObject(n), busId(bus_id), clock(_clock), width(_width),
         tickNextIdle(0), busIdle(this), inRetry(false), defaultPort(NULL)