1a2,13
> * Copyright (c) 2012 ARM Limited
> * All rights reserved.
> *
> * The license below extends only to copyright in the software and shall
> * not be construed as granting a license to any other intellectual
> * property including but not limited to intellectual property relating
> * to a hardware implementation of the functionality of the software
> * licensed hereunder. You may use the software subject to the license
> * terms below provided that you ensure that this notice is replicated
> * unmodified and in its entirety in all distributions of the software,
> * modified or unmodified, in source code or in binary form.
> *
28a41
> * Andreas Hansson
37,38c50,52
< SimpleTimingPort::SimpleTimingPort(string pname, MemObject *_owner)
< : Port(pname, _owner), sendEvent(NULL), drainEvent(NULL),
---
> SimpleTimingPort::SimpleTimingPort(const string &_name, MemObject *_owner,
> const string _label)
> : Port(_name, _owner), label(_label), sendEvent(this), drainEvent(NULL),
41,42d54
< sendEvent = new EventWrapper<SimpleTimingPort,
< &SimpleTimingPort::processSendEvent>(this);
47d58
< delete sendEvent;
52a64,65
> pkt->pushLabel(label);
>
54a68
> bool found = false;
56,62c70,74
< for (; i != end; ++i) {
< PacketPtr target = i->pkt;
< // If the target contains data, and it overlaps the
< // probed request, need to update data
< if (pkt->checkFunctional(target)) {
< return true;
< }
---
> while (!found && i != end) {
> // If the buffered packet contains data, and it overlaps the
> // current packet, then update data
> found = pkt->checkFunctional(i->pkt);
> ++i;
65c77,79
< return false;
---
> pkt->popLabel();
>
> return found;
110a125,126
> // if we are waiting on a retry, do not schedule a send event, and
> // instead rely on retry being called
112c128
< assert(!sendEvent->scheduled());
---
> assert(!sendEvent.scheduled());
116,119c132,135
< if (!sendEvent->scheduled()) {
< owner->schedule(sendEvent, when);
< } else if (sendEvent->when() > when) {
< owner->reschedule(sendEvent, when);
---
> if (!sendEvent.scheduled()) {
> owner->schedule(&sendEvent, when);
> } else if (sendEvent.when() > when) {
> owner->reschedule(&sendEvent, when);
156,158c172
<
< void
< SimpleTimingPort::sendDeferredPacket()
---
> void SimpleTimingPort::trySendTiming()
161,163c175,176
< // take packet off list here; if recvTiming() on the other side
< // calls sendTiming() back on us (like SimpleTimingCpu does), then
< // we get confused by having a non-active packet on transmitList
---
> // take the next packet off the list here, as we might return to
> // ourselves through the sendTiming call below
166d178
< bool success = sendTiming(dp.pkt);
168,172c180,181
< if (success) {
< if (!transmitList.empty() && !sendEvent->scheduled()) {
< Tick time = transmitList.front().tick;
< owner->schedule(sendEvent, time <= curTick() ? curTick()+1 : time);
< }
---
> // attempt to send the packet and remember the outcome
> waitingOnRetry = !sendTiming(dp.pkt);
174c183,204
< if (transmitList.empty() && drainEvent && !sendEvent->scheduled()) {
---
> if (waitingOnRetry) {
> // put the packet back at the front of the list (packet should
> // not have changed since it wasn't accepted)
> assert(!sendEvent.scheduled());
> transmitList.push_front(dp);
> }
> }
>
> void
> SimpleTimingPort::scheduleSend(Tick time)
> {
> // the next ready time is either determined by the next deferred packet,
> // or in the cache through the MSHR ready time
> Tick nextReady = std::min(deferredPacketReadyTime(), time);
> if (nextReady != MaxTick) {
> // if the sendTiming caused someone else to call our
> // recvTiming we could already have an event scheduled, check
> if (!sendEvent.scheduled())
> owner->schedule(&sendEvent, std::max(nextReady, curTick() + 1));
> } else {
> // no more to send, so if we're draining, we may be done
> if (drainEvent && !sendEvent.scheduled()) {
178,183d207
< } else {
< // Unsuccessful, need to put back on transmitList. Callee
< // should not have messed with it (since it didn't accept that
< // packet), so we can just push it back on the front.
< assert(!sendEvent->scheduled());
< transmitList.push_front(dp);
184a209
> }
186c211,215
< waitingOnRetry = !success;
---
> void
> SimpleTimingPort::sendDeferredPacket()
> {
> // try to send what is on the list
> trySendTiming();
188,189c217,220
< if (waitingOnRetry) {
< DPRINTF(Bus, "Send failed, waiting on retry\n");
---
> // if we succeeded and are not waiting for a retry, schedule the
> // next send
> if (!waitingOnRetry) {
> scheduleSend();
197a229,231
> // note that in the cache we get a retry even though we may not
> // have a packet to retry (we could potentially decide on a new
> // packet every time we retry)
214c248
< if (transmitList.size() == 0 && !sendEvent->scheduled())
---
> if (transmitList.empty() && !sendEvent.scheduled())