mem: Avoid unecessary retries when bus peer is not ready
authorAndreas Hansson <andreas.hansson@arm.com>
Wed, 3 Sep 2014 11:42:53 +0000 (07:42 -0400)
committerAndreas Hansson <andreas.hansson@arm.com>
Wed, 3 Sep 2014 11:42:53 +0000 (07:42 -0400)
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.

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

index 5ab7e5b0474c96ce4abee361ec6f9959777c2f05..730c612ca43b4199e6af51f954d04484e743a39f 100644 (file)
@@ -136,8 +136,7 @@ template <typename SrcType, typename DstType>
 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 @@ BaseBus::Layer<SrcType,DstType>::tryTiming(SrcType* src_port)
     // update the state to busy
     state = BUSY;
 
-    // reset the retrying port
-    retryingPort = NULL;
-
     return true;
 }
 
@@ -243,7 +239,10 @@ BaseBus::Layer<SrcType,DstType>::releaseLayer()
 
     // 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 @@ BaseBus::Layer<SrcType,DstType>::retryWaiting()
 
     // 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 @@ BaseBus::Layer<SrcType,DstType>::retryWaiting()
         // 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)));
index bdcf319f4f12ec9f1864ff7f1d3792b2fba4d7f7..f01a3ae7f067fe96f338f1b1a5944b76459de90f 100644 (file)
@@ -220,14 +220,6 @@ class BaseBus : public MemObject
          */
         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.