summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/packet_queue.cc53
-rw-r--r--src/mem/packet_queue.hh3
2 files changed, 16 insertions, 40 deletions
diff --git a/src/mem/packet_queue.cc b/src/mem/packet_queue.cc
index e7ad1cc47..a9fe29e86 100644
--- a/src/mem/packet_queue.cc
+++ b/src/mem/packet_queue.cc
@@ -119,29 +119,8 @@ PacketQueue::schedSendTiming(PacketPtr pkt, Tick when, bool force_order)
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
+ // nothing on the list
+ if (transmitList.empty()) {
transmitList.emplace_front(when, pkt);
schedSendEvent(when);
return;
@@ -155,21 +134,19 @@ PacketQueue::schedSendTiming(PacketPtr pkt, Tick when, bool force_order)
// ourselves again before we had a chance to update waitingOnRetry
// assert(waitingOnRetry || sendEvent.scheduled());
- // list is non-empty and this belongs at the end
- if (when >= transmitList.back().tick) {
- transmitList.emplace_back(when, pkt);
- 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
- while (i != transmitList.end() && when >= i->tick)
- ++i;
- transmitList.emplace(i, when, pkt);
+ // this belongs in the middle somewhere, so search from the end to
+ // order by tick; however, if force_order is set, also make sure
+ // not to re-order in front of some existing packet with the same
+ // address
+ auto i = transmitList.end();
+ --i;
+ while (i != transmitList.begin() && when < i->tick &&
+ !(force_order && i->pkt->getAddr() == pkt->getAddr()))
+ --i;
+
+ // emplace inserts the element before the position pointed to by
+ // the iterator, so advance it one step
+ transmitList.emplace(++i, when, pkt);
}
void
diff --git a/src/mem/packet_queue.hh b/src/mem/packet_queue.hh
index e9cf34bb0..866a4477a 100644
--- a/src/mem/packet_queue.hh
+++ b/src/mem/packet_queue.hh
@@ -176,8 +176,7 @@ class PacketQueue : public Drainable
*
* @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.
+ * @param force_order Force insertion order for packets with same address
*/
void schedSendTiming(PacketPtr pkt, Tick when, bool force_order = false);