MEM: Simplify ports by removing EventManager
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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
2
src/mem/cache/base.cc
vendored
2
src/mem/cache/base.cc
vendored
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
src/mem/cache/cache_impl.hh
vendored
2
src/mem/cache/cache_impl.hh
vendored
@@ -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()) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -29,12 +29,13 @@
|
||||
*/
|
||||
|
||||
#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()) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user