summaryrefslogtreecommitdiff
path: root/src/mem/tport.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/tport.cc')
-rw-r--r--src/mem/tport.cc58
1 files changed, 43 insertions, 15 deletions
diff --git a/src/mem/tport.cc b/src/mem/tport.cc
index cef7a2a5b..21907c0ca 100644
--- a/src/mem/tport.cc
+++ b/src/mem/tport.cc
@@ -33,8 +33,22 @@
void
SimpleTimingPort::recvFunctional(Packet *pkt)
{
- // just do an atomic access and throw away the returned latency
- recvAtomic(pkt);
+ //First check queued events
+ std::list<Packet *>::iterator i = transmitList.begin();
+ std::list<Packet *>::iterator end = transmitList.end();
+ bool cont = true;
+
+ while (i != end && cont) {
+ Packet * target = *i;
+ // If the target contains data, and it overlaps the
+ // probed request, need to update data
+ if (target->intersect(pkt))
+ fixPacket(pkt, target);
+
+ }
+ //Then just do an atomic access and throw away the returned latency
+ if (cont)
+ recvAtomic(pkt);
}
bool
@@ -58,13 +72,17 @@ SimpleTimingPort::recvTiming(Packet *pkt)
void
SimpleTimingPort::recvRetry()
{
- bool result = true;
- while (result && transmitList.size()) {
- result = sendTiming(transmitList.front());
- if (result)
- transmitList.pop_front();
+ assert(outTiming > 0);
+ assert(!transmitList.empty());
+ if (sendTiming(transmitList.front())) {
+ transmitList.pop_front();
+ outTiming--;
+ DPRINTF(Bus, "No Longer waiting on retry\n");
+ if (!transmitList.empty())
+ sendTimingLater(transmitList.front(), 1);
}
- if (transmitList.size() == 0 && drainEvent) {
+
+ if (transmitList.empty() && drainEvent) {
drainEvent->process();
drainEvent = NULL;
}
@@ -73,18 +91,28 @@ SimpleTimingPort::recvRetry()
void
SimpleTimingPort::SendEvent::process()
{
- port->outTiming--;
- assert(port->outTiming >= 0);
- if (port->sendTiming(packet)) {
- // send successfule
- if (port->transmitList.size() == 0 && port->drainEvent) {
+ assert(port->outTiming > 0);
+ if (!port->transmitList.empty() && port->transmitList.front() != packet) {
+ //We are not the head of the list
+ port->transmitList.push_back(packet);
+ } else if (port->sendTiming(packet)) {
+ // send successful
+ if (port->transmitList.size()) {
+ port->transmitList.pop_front();
+ port->outTiming--;
+ if (!port->transmitList.empty())
+ port->sendTimingLater(port->transmitList.front(), 1);
+ }
+ if (port->transmitList.empty() && port->drainEvent) {
port->drainEvent->process();
port->drainEvent = NULL;
}
} else {
// send unsuccessful (due to flow control). Will get retry
- // callback later; save for then.
- port->transmitList.push_back(packet);
+ // callback later; save for then if not already
+ DPRINTF(Bus, "Waiting on retry\n");
+ if (!(port->transmitList.front() == packet))
+ port->transmitList.push_back(packet);
}
}