// invalidate it.
pkt->cmd = MemCmd::ReadRespWithInvalidate;
}
- DPRINTF(Cache, "%s created response: %s address %x size %d\n",
- __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize());
- // Here we condiser forward_time, paying for just forward latency and
+ // Here we consider forward_time, paying for just forward latency and
// also charging the delay provided by the xbar.
// forward_time is used as send_time in next allocateWriteBuffer().
Tick forward_time = clockEdge(forwardLatency) + pkt->headerDelay;
// Here we reset the timing of the packet.
pkt->headerDelay = pkt->payloadDelay = 0;
- memSidePort->schedTimingSnoopResp(pkt, forward_time);
+ DPRINTF(Cache, "%s created response: %s address %x size %d tick: %lu\n",
+ __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize(),
+ forward_time);
+ memSidePort->schedTimingSnoopResp(pkt, forward_time, true);
}
template<class TagStore>
}
void
-PacketQueue::schedSendTiming(PacketPtr pkt, Tick when)
+PacketQueue::schedSendTiming(PacketPtr pkt, Tick when, bool force_order)
{
- DPRINTF(PacketQueue, "%s for %s address %x size %d\n", __func__,
- pkt->cmdString(), pkt->getAddr(), pkt->getSize());
+ DPRINTF(PacketQueue, "%s for %s address %x size %d when %lu ord: %i\n",
+ __func__, pkt->cmdString(), pkt->getAddr(), pkt->getSize(), when,
+ force_order);
// we can still send a packet before the end of this tick
assert(when >= curTick());
name());
}
+ // if requested, force the timing to be in-order by changing the when
+ // parameter
+ if (force_order && !transmitList.empty()) {
+ Tick back = transmitList.back().tick;
+
+ // fudge timing if required; relies on the code below to do the right
+ // thing (push_back) with the updated time-stamp
+ if (when < back) {
+ DPRINTF(PacketQueue, "%s force_order shifted packet %s address "\
+ "%x from %lu to %lu\n", __func__, pkt->cmdString(),
+ pkt->getAddr(), when, back);
+ when = back;
+ }
+ }
+
// nothing on the list, or earlier than current front element,
// schedule an event
if (transmitList.empty() || when < transmitList.front().tick) {
+ // force_order-ed in here only when list is empty
+ assert(!force_order || transmitList.empty());
// note that currently we ignore a potentially outstanding retry
// and could in theory put a new packet at the head of the
// transmit list before retrying the existing packet
return;
}
+ // forced orders never need insertion in the middle
+ assert(!force_order);
+
// this belongs in the middle somewhere, insertion sort
auto i = transmitList.begin();
++i; // already checked for insertion at front
*
* @param pkt Packet to send
* @param when Absolute time (in ticks) to send packet
+ * @param force_order Do not reorder packets despite timing, but keep them
+ * in insertion order.
*/
- void schedSendTiming(PacketPtr pkt, Tick when);
+ void schedSendTiming(PacketPtr pkt, Tick when, bool force_order = false);
/**
* Retry sending a packet from the queue. Note that this is not
* @param pkt Packet to send
* @param when Absolute time (in ticks) to send packet
*/
- void schedTimingSnoopResp(PacketPtr pkt, Tick when)
- { snoopRespQueue.schedSendTiming(pkt, when); }
+ void schedTimingSnoopResp(PacketPtr pkt, Tick when, bool force_order =
+ false)
+ { snoopRespQueue.schedSendTiming(pkt, when, force_order); }
/** Check the list of buffered packets against the supplied
* functional request. */