diff --git a/src/traffic-control/model/codel-queue-disc.cc b/src/traffic-control/model/codel-queue-disc.cc index dd7cb2d2f..4d1b01045 100644 --- a/src/traffic-control/model/codel-queue-disc.cc +++ b/src/traffic-control/model/codel-queue-disc.cc @@ -474,18 +474,18 @@ CoDelQueueDisc::GetDropNext (void) } Ptr -CoDelQueueDisc::DoPeek (void) const +CoDelQueueDisc::DoPeek (void) { NS_LOG_FUNCTION (this); - if (GetInternalQueue (0)->IsEmpty ()) + Ptr item = PeekDequeued (); + + if (!item) { NS_LOG_LOGIC ("Queue empty"); return 0; } - Ptr item = GetInternalQueue (0)->Peek (); - NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ()); NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ()); diff --git a/src/traffic-control/model/codel-queue-disc.h b/src/traffic-control/model/codel-queue-disc.h index 33c4ec724..5280b3209 100644 --- a/src/traffic-control/model/codel-queue-disc.h +++ b/src/traffic-control/model/codel-queue-disc.h @@ -192,7 +192,7 @@ private: */ virtual Ptr DoDequeue (void); - virtual Ptr DoPeek (void) const; + virtual Ptr DoPeek (void); virtual bool CheckConfig (void); /** diff --git a/src/traffic-control/model/fq-codel-queue-disc.cc b/src/traffic-control/model/fq-codel-queue-disc.cc index c5b5c4e66..665c25b13 100644 --- a/src/traffic-control/model/fq-codel-queue-disc.cc +++ b/src/traffic-control/model/fq-codel-queue-disc.cc @@ -295,29 +295,11 @@ FqCoDelQueueDisc::DoDequeue (void) } Ptr -FqCoDelQueueDisc::DoPeek (void) const +FqCoDelQueueDisc::DoPeek (void) { NS_LOG_FUNCTION (this); - Ptr flow; - - if (!m_newFlows.empty ()) - { - flow = m_newFlows.front (); - } - else - { - if (!m_oldFlows.empty ()) - { - flow = m_oldFlows.front (); - } - else - { - return 0; - } - } - - return flow->GetQueueDisc ()->Peek (); + return PeekDequeued (); } void diff --git a/src/traffic-control/model/fq-codel-queue-disc.h b/src/traffic-control/model/fq-codel-queue-disc.h index 44309b2d6..06f5e930d 100644 --- a/src/traffic-control/model/fq-codel-queue-disc.h +++ b/src/traffic-control/model/fq-codel-queue-disc.h @@ -151,7 +151,7 @@ private: virtual bool DoEnqueue (Ptr item); virtual Ptr DoDequeue (void); - virtual Ptr DoPeek (void) const; + virtual Ptr DoPeek (void); virtual bool CheckConfig (void); virtual void InitializeParams (void); diff --git a/src/traffic-control/model/mq-queue-disc.cc b/src/traffic-control/model/mq-queue-disc.cc index 50a37c0c2..fc2440f63 100644 --- a/src/traffic-control/model/mq-queue-disc.cc +++ b/src/traffic-control/model/mq-queue-disc.cc @@ -68,7 +68,7 @@ MqQueueDisc::DoDequeue (void) } Ptr -MqQueueDisc::DoPeek (void) const +MqQueueDisc::DoPeek (void) { NS_FATAL_ERROR ("MqQueueDisc: DoPeek should never be called"); } diff --git a/src/traffic-control/model/mq-queue-disc.h b/src/traffic-control/model/mq-queue-disc.h index 8bf23c477..22bf10954 100644 --- a/src/traffic-control/model/mq-queue-disc.h +++ b/src/traffic-control/model/mq-queue-disc.h @@ -56,7 +56,7 @@ public: private: virtual bool DoEnqueue (Ptr item); virtual Ptr DoDequeue (void); - virtual Ptr DoPeek (void) const; + virtual Ptr DoPeek (void); virtual bool CheckConfig (void); virtual void InitializeParams (void); }; diff --git a/src/traffic-control/model/pfifo-fast-queue-disc.cc b/src/traffic-control/model/pfifo-fast-queue-disc.cc index 86a805ccb..28c90224b 100644 --- a/src/traffic-control/model/pfifo-fast-queue-disc.cc +++ b/src/traffic-control/model/pfifo-fast-queue-disc.cc @@ -128,7 +128,7 @@ PfifoFastQueueDisc::DoDequeue (void) } Ptr -PfifoFastQueueDisc::DoPeek (void) const +PfifoFastQueueDisc::DoPeek (void) { NS_LOG_FUNCTION (this); diff --git a/src/traffic-control/model/pfifo-fast-queue-disc.h b/src/traffic-control/model/pfifo-fast-queue-disc.h index 890b70d58..4a2c8f245 100644 --- a/src/traffic-control/model/pfifo-fast-queue-disc.h +++ b/src/traffic-control/model/pfifo-fast-queue-disc.h @@ -92,7 +92,7 @@ private: virtual bool DoEnqueue (Ptr item); virtual Ptr DoDequeue (void); - virtual Ptr DoPeek (void) const; + virtual Ptr DoPeek (void); virtual bool CheckConfig (void); virtual void InitializeParams (void); }; diff --git a/src/traffic-control/model/pie-queue-disc.cc b/src/traffic-control/model/pie-queue-disc.cc index db2608f88..dd1405f64 100644 --- a/src/traffic-control/model/pie-queue-disc.cc +++ b/src/traffic-control/model/pie-queue-disc.cc @@ -474,17 +474,18 @@ PieQueueDisc::DoDequeue () } Ptr -PieQueueDisc::DoPeek () const +PieQueueDisc::DoPeek () { NS_LOG_FUNCTION (this); - if (GetInternalQueue (0)->IsEmpty ()) + + Ptr item = PeekDequeued (); + + if (!item) { NS_LOG_LOGIC ("Queue empty"); return 0; } - Ptr item = GetInternalQueue (0)->Peek (); - NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ()); NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ()); diff --git a/src/traffic-control/model/pie-queue-disc.h b/src/traffic-control/model/pie-queue-disc.h index 64e4e55d2..105ad2c9f 100644 --- a/src/traffic-control/model/pie-queue-disc.h +++ b/src/traffic-control/model/pie-queue-disc.h @@ -152,7 +152,7 @@ protected: private: virtual bool DoEnqueue (Ptr item); virtual Ptr DoDequeue (void); - virtual Ptr DoPeek (void) const; + virtual Ptr DoPeek (void); virtual bool CheckConfig (void); /** diff --git a/src/traffic-control/model/queue-disc.cc b/src/traffic-control/model/queue-disc.cc index f4618a701..34044a1cb 100644 --- a/src/traffic-control/model/queue-disc.cc +++ b/src/traffic-control/model/queue-disc.cc @@ -870,12 +870,43 @@ QueueDisc::Dequeue (void) } Ptr -QueueDisc::Peek (void) const +QueueDisc::Peek (void) { NS_LOG_FUNCTION (this); return DoPeek (); } +Ptr +QueueDisc::PeekDequeued (void) +{ + NS_LOG_FUNCTION (this); + + if (!m_requeued) + { + m_requeued = Dequeue (); + } + return m_requeued; +} + +Ptr +QueueDisc::DequeuePeeked (void) +{ + NS_LOG_FUNCTION (this); + + Ptr item = m_requeued; + + if (item) + { + m_requeued = 0; + } + else + { + item = Dequeue (); + } + + return item; +} + void QueueDisc::Run (void) { diff --git a/src/traffic-control/model/queue-disc.h b/src/traffic-control/model/queue-disc.h index 784187f2a..e93734cb9 100644 --- a/src/traffic-control/model/queue-disc.h +++ b/src/traffic-control/model/queue-disc.h @@ -384,7 +384,15 @@ public: * DoPeek function, which must be implemented by derived classes. * \return 0 if the operation was not successful; the item otherwise. */ - Ptr Peek (void) const; + Ptr Peek (void); + + /** + * Extract from the queue disc the packet that has been dequeued by calling + * PeekDequeued. + * + * \return 0 if the operation was not successful; the item otherwise. + */ + Ptr DequeuePeeked (void); /** * Modelled after the Linux function __qdisc_run (net/sched/sch_generic.c) @@ -535,6 +543,21 @@ protected: */ bool Mark (Ptr item, const char* reason); + /** + * Dequeue a packet and retain it in the queue disc as a requeued packet. + * The packet is not traced as requeued, nor is the total count of requeued + * packets increased. The dequeued packet is not counted in the backlog of + * the queue disc and is actually extracted from the queue disc by calling + * DequeuePeeked. Queue discs can point their DoPeek method to this one. This + * is recommended especially for queue discs for which it is not obvious what + * is the next packet that will be dequeued (e.g., queue discs having multiple + * internal queues or child queue discs or queue discs that drop packets + * after dequeue). + * + * \return 0 if the operation was not successful; the item otherwise. + */ + Ptr PeekDequeued (void); + private: /** * \brief Copy constructor @@ -570,7 +593,7 @@ private: * This function returns a copy of the next packet the queue disc will extract. * \return 0 if the operation was not successful; the packet otherwise. */ - virtual Ptr DoPeek (void) const = 0; + virtual Ptr DoPeek (void) = 0; /** * Check whether the current configuration is correct. Default objects (such diff --git a/src/traffic-control/model/red-queue-disc.cc b/src/traffic-control/model/red-queue-disc.cc index 79c363a63..261bca23d 100644 --- a/src/traffic-control/model/red-queue-disc.cc +++ b/src/traffic-control/model/red-queue-disc.cc @@ -885,7 +885,7 @@ RedQueueDisc::DoDequeue (void) } Ptr -RedQueueDisc::DoPeek (void) const +RedQueueDisc::DoPeek (void) { NS_LOG_FUNCTION (this); if (GetInternalQueue (0)->IsEmpty ()) diff --git a/src/traffic-control/model/red-queue-disc.h b/src/traffic-control/model/red-queue-disc.h index 2d1474355..f3dc97be9 100644 --- a/src/traffic-control/model/red-queue-disc.h +++ b/src/traffic-control/model/red-queue-disc.h @@ -246,7 +246,7 @@ protected: private: virtual bool DoEnqueue (Ptr item); virtual Ptr DoDequeue (void); - virtual Ptr DoPeek (void) const; + virtual Ptr DoPeek (void); virtual bool CheckConfig (void); /**