summaryrefslogtreecommitdiff
path: root/src/mem/packet_queue.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem/packet_queue.cc')
-rw-r--r--src/mem/packet_queue.cc27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/mem/packet_queue.cc b/src/mem/packet_queue.cc
index 29f6d2903..1b2c69930 100644
--- a/src/mem/packet_queue.cc
+++ b/src/mem/packet_queue.cc
@@ -100,10 +100,11 @@ PacketQueue::checkFunctional(PacketPtr pkt)
}
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());
@@ -118,9 +119,26 @@ PacketQueue::schedSendTiming(PacketPtr pkt, Tick when)
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
@@ -143,6 +161,9 @@ PacketQueue::schedSendTiming(PacketPtr pkt, Tick when)
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