diff options
Diffstat (limited to 'src/mem/tport.cc')
-rw-r--r-- | src/mem/tport.cc | 58 |
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); } } |