changeset d548d1d7597c in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=d548d1d7597c
description:
        mem: Avoid unecessary retries when bus peer is not ready

        This patch removes unecessary retries that happened when the bus layer
        itself was no longer busy, but the the peer was not yet ready. Instead
        of sending a retry that will inevitably not succeed, the bus now
        silenty waits until the peer sends a retry.

diffstat:

 src/mem/bus.cc |  15 ++++++---------
 src/mem/bus.hh |   8 --------
 2 files changed, 6 insertions(+), 17 deletions(-)

diffs (71 lines):

diff -r d96b61d843b2 -r d548d1d7597c src/mem/bus.cc
--- a/src/mem/bus.cc    Wed Sep 03 07:42:52 2014 -0400
+++ b/src/mem/bus.cc    Wed Sep 03 07:42:53 2014 -0400
@@ -136,8 +136,7 @@
 BaseBus::Layer<SrcType,DstType>::Layer(DstType& _port, BaseBus& _bus,
                                        const std::string& _name) :
     port(_port), bus(_bus), _name(_name), state(IDLE), drainManager(NULL),
-    retryingPort(NULL), waitingForPeer(NULL),
-    releaseEvent(this)
+    waitingForPeer(NULL), releaseEvent(this)
 {
 }
 
@@ -190,9 +189,6 @@
     // update the state to busy
     state = BUSY;
 
-    // reset the retrying port
-    retryingPort = NULL;
-
     return true;
 }
 
@@ -243,7 +239,10 @@
 
     // bus layer is now idle, so if someone is waiting we can retry
     if (!waitingForLayer.empty()) {
-        retryWaiting();
+        // there is no point in sending a retry if someone is still
+        // waiting for the peer
+        if (waitingForPeer == NULL)
+            retryWaiting();
     } else if (waitingForPeer == NULL && drainManager) {
         DPRINTF(Drain, "Bus done draining, signaling drain manager\n");
         //If we weren't able to drain before, do it now.
@@ -268,8 +267,7 @@
 
     // set the retrying port to the front of the retry list and pop it
     // off the list
-    assert(retryingPort == NULL);
-    retryingPort = waitingForLayer.front();
+    SrcType* retryingPort = waitingForLayer.front();
     waitingForLayer.pop_front();
 
     // tell the port to retry, which in some cases ends up calling the
@@ -282,7 +280,6 @@
         // update the state to busy and reset the retrying port, we
         // have done our bit and sent the retry
         state = BUSY;
-        retryingPort = NULL;
 
         // occupy the bus layer until the next cycle ends
         occupyLayer(bus.clockEdge(Cycles(1)));
diff -r d96b61d843b2 -r d548d1d7597c src/mem/bus.hh
--- a/src/mem/bus.hh    Wed Sep 03 07:42:52 2014 -0400
+++ b/src/mem/bus.hh    Wed Sep 03 07:42:53 2014 -0400
@@ -221,14 +221,6 @@
         std::deque<SrcType*> waitingForLayer;
 
         /**
-         * Port that we are currently in the process of telling to
-         * retry a previously failed attempt to perform a timing
-         * transaction. This is a valid port when in the retry state,
-         * and NULL when in busy or idle.
-         */
-        SrcType* retryingPort;
-
-        /**
          * Track who is waiting for the retry when receiving it from a
          * peer. If no port is waiting NULL is stored.
          */
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to