diff options
Diffstat (limited to 'src/mem/tport.hh')
-rw-r--r-- | src/mem/tport.hh | 66 |
1 files changed, 47 insertions, 19 deletions
diff --git a/src/mem/tport.hh b/src/mem/tport.hh index 3d28ea3e5..ea0f05ed1 100644 --- a/src/mem/tport.hh +++ b/src/mem/tport.hh @@ -58,9 +58,26 @@ class SimpleTimingPort : public Port { protected: + /** A deferred packet, buffered to transmit later. */ + class DeferredPacket { + public: + Tick tick; ///< The tick when the packet is ready to transmit + PacketPtr pkt; ///< Pointer to the packet to transmit + DeferredPacket(Tick t, PacketPtr p) + : tick(t), pkt(p) + {} + }; + + typedef std::list<DeferredPacket> DeferredPacketList; + typedef std::list<DeferredPacket>::iterator DeferredPacketIterator; + /** A list of outgoing timing response packets that haven't been * serviced yet. */ - std::list<std::pair<Tick,PacketPtr> > transmitList; + DeferredPacketList transmitList; + + /** This function attempts to send deferred packets. Scheduled to + * be called in the future via SendEvent. */ + void processSendEvent(); /** * This class is used to implemented sendTiming() with a delay. When @@ -68,32 +85,38 @@ class SimpleTimingPort : public Port * When the event time expires it attempts to send the packet. * If it cannot, the packet sent when recvRetry() is called. **/ - class SendEvent : public Event - { - SimpleTimingPort *port; - - public: - SendEvent(SimpleTimingPort *p) - : Event(&mainEventQueue), port(p) - { } - - virtual void process(); + typedef EventWrapper<SimpleTimingPort, &SimpleTimingPort::processSendEvent> + SendEvent; - virtual const char *description() - { return "Future scheduled sendTiming event"; } - }; - - SendEvent sendEvent; + Event *sendEvent; /** If we need to drain, keep the drain event around until we're done * here.*/ Event *drainEvent; + /** Remember whether we're awaiting a retry from the bus. */ + bool waitingOnRetry; + + /** Check the list of buffered packets against the supplied + * functional request. */ + void checkFunctional(PacketPtr funcPkt); + + /** Check whether we have a packet ready to go on the transmit list. */ + bool deferredPacketReady() + { return !transmitList.empty() && transmitList.front().tick <= curTick; } + /** Schedule a sendTiming() event to be called in the future. * @param pkt packet to send - * @param time increment from now (in ticks) to send packet + * @param absolute time (in ticks) to send packet + */ + void schedSendTiming(PacketPtr pkt, Tick when); + + /** Attempt to send the packet at the head of the deferred packet + * list. Caller must guarantee that the deferred packet list is + * non-empty and that the head packet is scheduled for curTick (or + * earlier). */ - void sendTiming(PacketPtr pkt, Tick time); + void sendDeferredPacket(); /** This function is notification that the device should attempt to send a * packet again. */ @@ -115,9 +138,14 @@ class SimpleTimingPort : public Port public: SimpleTimingPort(std::string pname, MemObject *_owner = NULL) - : Port(pname, _owner), sendEvent(this), drainEvent(NULL) + : Port(pname, _owner), + sendEvent(new SendEvent(this)), + drainEvent(NULL), + waitingOnRetry(false) {} + ~SimpleTimingPort() { delete sendEvent; } + /** Hook for draining timing accesses from the system. The * associated SimObject's drain() functions should be implemented * something like this when this class is used: |