MEM: Simplify ports by removing EventManager
authorAndreas Hansson <andreas.hansson@arm.com>
Tue, 17 Jan 2012 18:55:09 +0000 (12:55 -0600)
committerAndreas Hansson <andreas.hansson@arm.com>
Tue, 17 Jan 2012 18:55:09 +0000 (12:55 -0600)
This patch removes the inheritance of EventManager from the ports and
moves all responsibility for event queues to the owner. Eventually the
event manager should be the interface block, which could either be the
structural owner or a subblock like a LSQ in the O3 CPU for example.

src/cpu/simple/timing.cc
src/dev/io_device.cc
src/mem/bridge.cc
src/mem/cache/base.cc
src/mem/cache/cache_impl.hh
src/mem/port.cc
src/mem/port.hh
src/mem/tport.cc
src/mem/tport.hh

index 70583cae968b98d729bf38ffe2ab8ab1b9b20d78..f8d13efd92c60326cb996ee35ea58b26e0898de1 100644 (file)
@@ -862,7 +862,7 @@ TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
                 // faster than a CPU we could get two responses before
                 // next_tick expires
                 if (!retryEvent.scheduled())
-                    schedule(retryEvent, next_tick);
+                    cpu->schedule(retryEvent, next_tick);
                 return false;
             }
         }
index 00e463de1016780d86834c37e9df63308cfd46d7..9b7b6ec500632f2d130bf96788e568ab062e7f78 100644 (file)
@@ -136,7 +136,7 @@ DmaPort::recvTiming(PacketPtr pkt)
         else if (backoffTime < maxBackoffDelay)
             backoffTime <<= 1;
 
-        reschedule(backoffEvent, curTick() + backoffTime, true);
+        device->reschedule(backoffEvent, curTick() + backoffTime, true);
 
         DPRINTF(DMA, "Backoff time set to %d ticks\n", backoffTime);
 
@@ -164,7 +164,8 @@ DmaPort::recvTiming(PacketPtr pkt)
         if (state->totBytes == state->numBytes) {
             if (state->completionEvent) {
                 if (state->delay)
-                    schedule(state->completionEvent, curTick() + state->delay);
+                    device->schedule(state->completionEvent,
+                                     curTick() + state->delay);
                 else
                     state->completionEvent->process();
             }
@@ -234,7 +235,7 @@ DmaPort::recvRetry()
     if (transmitList.size() && backoffTime && !inRetry) {
         DPRINTF(DMA, "Scheduling backoff for %d\n", curTick()+backoffTime);
         if (!backoffEvent.scheduled())
-            schedule(backoffEvent, backoffTime + curTick());
+            device->schedule(backoffEvent, backoffTime + curTick());
     }
     DPRINTF(DMA, "TransmitList: %d, backoffTime: %d inRetry: %d es: %d\n",
             transmitList.size(), backoffTime, inRetry,
@@ -320,7 +321,7 @@ DmaPort::sendDma()
                 !backoffEvent.scheduled()) {
             DPRINTF(DMA, "-- Scheduling backoff timer for %d\n",
                     backoffTime+curTick());
-            schedule(backoffEvent, backoffTime + curTick());
+            device->schedule(backoffEvent, backoffTime + curTick());
         }
     } else if (state == Enums::atomic) {
         transmitList.pop_front();
@@ -342,7 +343,8 @@ DmaPort::sendDma()
         if (state->totBytes == state->numBytes) {
             if (state->completionEvent) {
                 assert(!state->completionEvent->scheduled());
-                schedule(state->completionEvent, curTick() + lat + state->delay);
+                device->schedule(state->completionEvent,
+                                 curTick() + lat + state->delay);
             }
             delete state;
             delete pkt->req;
index 9e5e640694dcb029f799dd7d1df6748a507601e9..65ce3012e2950838c55091591836daad98cf2d03 100644 (file)
@@ -165,7 +165,7 @@ Bridge::BridgePort::nackRequest(PacketPtr pkt)
     // nothing on the list, add it and we're done
     if (sendQueue.empty()) {
         assert(!sendEvent.scheduled());
-        schedule(sendEvent, readyTime);
+        bridge->schedule(sendEvent, readyTime);
         sendQueue.push_back(buf);
         return;
     }
@@ -187,7 +187,7 @@ Bridge::BridgePort::nackRequest(PacketPtr pkt)
     while (i != end && !done) {
         if (readyTime < (*i)->ready) {
             if (i == begin)
-                reschedule(sendEvent, readyTime);
+                bridge->reschedule(sendEvent, readyTime);
             sendQueue.insert(i,buf);
             done = true;
         }
@@ -230,7 +230,7 @@ Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
     // should already be an event scheduled for sending the head
     // packet.
     if (sendQueue.empty()) {
-        schedule(sendEvent, readyTime);
+        bridge->schedule(sendEvent, readyTime);
     }
     sendQueue.push_back(buf);
 }
@@ -284,7 +284,7 @@ Bridge::BridgePort::trySend()
         if (!sendQueue.empty()) {
             buf = sendQueue.front();
             DPRINTF(BusBridge, "Scheduling next send\n");
-            schedule(sendEvent, std::max(buf->ready, curTick() + 1));
+            bridge->schedule(sendEvent, std::max(buf->ready, curTick() + 1));
         }
     } else {
         DPRINTF(BusBridge, "  unsuccessful\n");
@@ -305,7 +305,7 @@ Bridge::BridgePort::recvRetry()
     if (nextReady <= curTick())
         trySend();
     else
-        schedule(sendEvent, nextReady);
+        bridge->schedule(sendEvent, nextReady);
 }
 
 /** Function called by the port when the bus is receiving a Atomic
index 7863edde017e800f1db9a8fdf73da6b30b32bc92..023b743231e8ce933047b35227e9f962ae0e35e6 100644 (file)
@@ -126,7 +126,7 @@ BaseCache::CachePort::clearBlocked()
         mustSendRetry = false;
         SendRetryEvent *ev = new SendRetryEvent(this, true);
         // @TODO: need to find a better time (next bus cycle?)
-        schedule(ev, curTick() + 1);
+        cache->schedule(ev, curTick() + 1);
     }
 }
 
index 453e62b1a79348e84275258f2257794ef13db234..581435010893f7475c819629597d8fd51e58a8a6 100644 (file)
@@ -1729,7 +1729,7 @@ Cache<TagStore>::MemSidePort::sendPacket()
         // @TODO: need to facotr in prefetch requests here somehow
         if (nextReady != MaxTick) {
             DPRINTF(CachePort, "more packets to send @ %d\n", nextReady);
-            schedule(sendEvent, std::max(nextReady, curTick() + 1));
+            cache->schedule(sendEvent, std::max(nextReady, curTick() + 1));
         } else {
             // no more to send right now: if we're draining, we may be done
             if (drainEvent && !sendEvent->scheduled()) {
index c87785a49340c929925799042878274e3473c098..946f087ebae2f6d351f3932e776f6ea442d0cfc6 100644 (file)
@@ -93,8 +93,7 @@ class DefaultPeerPort : public Port
 DefaultPeerPort defaultPeerPort;
 
 Port::Port(const std::string &_name, MemObject *_owner)
-    : EventManager(_owner), portName(_name), peer(&defaultPeerPort),
-      owner(_owner)
+    : portName(_name), peer(&defaultPeerPort), owner(_owner)
 {
 }
 
@@ -113,7 +112,6 @@ Port::setPeer(Port *port)
 void
 Port::setOwner(MemObject *_owner)
 {
-    eventq = _owner->queue();
     owner = _owner;
 }
 
index c787f9f5106ee24bbd4e364bc6be6fa0d5e346ab..32f331433df72ddb593db0617564a75a7b8a8a5c 100644 (file)
@@ -47,7 +47,6 @@
 #include "base/types.hh"
 #include "mem/packet.hh"
 #include "mem/request.hh"
-#include "sim/eventq.hh"
 
 /** This typedef is used to clean up the parameter list of
  * getDeviceAddressRanges() and getPeerAddressRanges().  It's declared
@@ -59,7 +58,6 @@
 typedef std::list<Range<Addr> > AddrRangeList;
 typedef std::list<Range<Addr> >::iterator AddrRangeIter;
 
-class EventQueue;
 class MemObject;
 
 /**
@@ -73,7 +71,7 @@ class MemObject;
  * Send accessor functions are being called from the device the port is
  * associated with, and it will call the peer recv. accessor function.
  */
-class Port : public EventManager
+class Port
 {
   protected:
     /** Descriptive name (for DPRINTF output) */
index 8e02215f275cc3dd2dc81eb4af61df3c06901d2c..7b1fdb85004889e3de6e9a17cad395ff6b09178a 100644 (file)
  */
 
 #include "debug/Bus.hh"
+#include "mem/mem_object.hh"
 #include "mem/tport.hh"
 
 using namespace std;
 
 SimpleTimingPort::SimpleTimingPort(string pname, MemObject *_owner)
-    : Port(pname, _owner), sendEvent(0), drainEvent(NULL),
+    : Port(pname, _owner), sendEvent(NULL), drainEvent(NULL),
       waitingOnRetry(false)
 {
     sendEvent =  new EventWrapper<SimpleTimingPort,
@@ -104,6 +105,20 @@ SimpleTimingPort::recvTiming(PacketPtr pkt)
     return true;
 }
 
+void
+SimpleTimingPort::schedSendEvent(Tick when)
+{
+    if (waitingOnRetry) {
+        assert(!sendEvent->scheduled());
+        return;
+    }
+
+    if (!sendEvent->scheduled()) {
+        owner->schedule(sendEvent, when);
+    } else if (sendEvent->when() > when) {
+        owner->reschedule(sendEvent, when);
+    }
+}
 
 void
 SimpleTimingPort::schedSendTiming(PacketPtr pkt, Tick when)
@@ -153,7 +168,7 @@ SimpleTimingPort::sendDeferredPacket()
     if (success) {
         if (!transmitList.empty() && !sendEvent->scheduled()) {
             Tick time = transmitList.front().tick;
-            schedule(sendEvent, time <= curTick() ? curTick()+1 : time);
+            owner->schedule(sendEvent, time <= curTick() ? curTick()+1 : time);
         }
 
         if (transmitList.empty() && drainEvent && !sendEvent->scheduled()) {
index f081d8656d78a32b1c5c95489dfe7967f4684974..9143562fcae5c6c6f14adecd20ad7196909461d0 100644 (file)
@@ -106,21 +106,14 @@ class SimpleTimingPort : public Port
     Tick deferredPacketReadyTime()
     { return transmitList.empty() ? MaxTick : transmitList.front().tick; }
 
-    void
-    schedSendEvent(Tick when)
-    {
-        if (waitingOnRetry) {
-            assert(!sendEvent->scheduled());
-            return;
-        }
-
-        if (!sendEvent->scheduled()) {
-            schedule(sendEvent, when);
-        } else if (sendEvent->when() > when) {
-            reschedule(sendEvent, when);
-        }
-    }
-
+    /**
+     * Schedule a send even if not already waiting for a retry. If the
+     * requested time is before an already scheduled send event it
+     * will be rescheduled.
+     *
+     * @param when
+     */
+    void schedSendEvent(Tick when);
 
     /** Schedule a sendTiming() event to be called in the future.
      * @param pkt packet to send