diff --git a/CHANGES.html b/CHANGES.html
index 9ede25951..e2f7365fa 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -103,6 +103,11 @@ us a note on ns-developers mailing list.
Two new methods, QueueDisc::DropBeforeEnqueue() and QueueDisc::DropAfterDequeue() have
been introduced to replace QueueDisc::Drop(). Correspondingly, two new trace sources have been added to the QueueDisc class: DropBeforeEnqueue and DropAfterDequeue.
+
A new trace source, SojournTime, is exported by the QueueDisc base class to provide the
+ sojourn time of every packet dequeued from a queue disc. This has been made possible by adding a
+ timestamp to QueueDiscItem objects, which can be set/get through the new GetTimeStamp() and
+ SetTimeStamp() methods of the QueueDiscItem class.
+
Changes to existing API:
diff --git a/examples/traffic-control/traffic-control.cc b/examples/traffic-control/traffic-control.cc
index 2febdb461..7a0fd1168 100644
--- a/examples/traffic-control/traffic-control.cc
+++ b/examples/traffic-control/traffic-control.cc
@@ -78,6 +78,12 @@ DevicePacketsInQueueTrace (uint32_t oldValue, uint32_t newValue)
std::cout << "DevicePacketsInQueue " << oldValue << " to " << newValue << std::endl;
}
+void
+SojournTimeTrace (Time oldValue, Time newValue)
+{
+ std::cout << "Sojourn time " << newValue << std::endl;
+}
+
int
main (int argc, char *argv[])
{
@@ -120,9 +126,8 @@ main (int argc, char *argv[])
Ptr q = qdiscs.Get (1);
q->TraceConnectWithoutContext ("PacketsInQueue", MakeCallback (&TcPacketsInQueueTrace));
- // Alternatively:
- // Config::ConnectWithoutContext ("/NodeList/1/$ns3::TrafficControlLayer/RootQueueDiscList/0/PacketsInQueue",
- // MakeCallback (&TcPacketsInQueueTrace));
+ Config::ConnectWithoutContext ("/NodeList/1/$ns3::TrafficControlLayer/RootQueueDiscList/0/SojournTime",
+ MakeCallback (&SojournTimeTrace));
Ptr nd = devices.Get (1);
Ptr ptpnd = DynamicCast (nd);
diff --git a/src/network/utils/queue-item.cc b/src/network/utils/queue-item.cc
index 259bbc58c..aab3b330d 100644
--- a/src/network/utils/queue-item.cc
+++ b/src/network/utils/queue-item.cc
@@ -115,6 +115,20 @@ QueueDiscItem::SetTxQueueIndex (uint8_t txq)
m_txq = txq;
}
+Time
+QueueDiscItem::GetTimeStamp (void) const
+{
+ NS_LOG_FUNCTION (this);
+ return m_tstamp;
+}
+
+void
+QueueDiscItem::SetTimeStamp (Time t)
+{
+ NS_LOG_FUNCTION (this << t);
+ m_tstamp = t;
+}
+
void
QueueDiscItem::Print (std::ostream& os) const
{
diff --git a/src/network/utils/queue-item.h b/src/network/utils/queue-item.h
index 3d267d89a..18fb7c635 100644
--- a/src/network/utils/queue-item.h
+++ b/src/network/utils/queue-item.h
@@ -23,6 +23,7 @@
#include "ns3/ptr.h"
#include "ns3/simple-ref-count.h"
#include
+#include "ns3/nstime.h"
namespace ns3 {
@@ -180,6 +181,18 @@ public:
*/
void SetTxQueueIndex (uint8_t txq);
+ /**
+ * \brief Get the timestamp included in this item
+ * \return the timestamp included in this item.
+ */
+ Time GetTimeStamp (void) const;
+
+ /**
+ * \brief Set the timestamp included in this item
+ * \param t the timestamp to include in this item.
+ */
+ void SetTimeStamp (Time t);
+
/**
* \brief Add the header to the packet
*
@@ -226,6 +239,7 @@ private:
Address m_address; //!< MAC destination address
uint16_t m_protocol; //!< L3 Protocol number
uint8_t m_txq; //!< Transmission queue index
+ Time m_tstamp; //!< timestamp when the packet was enqueued
};
} // namespace ns3
diff --git a/src/traffic-control/doc/queue-discs.rst b/src/traffic-control/doc/queue-discs.rst
index ac9dd1103..fe9e72086 100644
--- a/src/traffic-control/doc/queue-discs.rst
+++ b/src/traffic-control/doc/queue-discs.rst
@@ -70,6 +70,13 @@ of the queue disc. The following identities hold:
* queued = enqueued - dequeued
* sent = dequeued - dropped after dequeue (- 1 if there is a requeued packet)
+The QueueDisc base class provides the SojournTime trace source, which provides
+the sojourn time of every packet dequeued from a queue disc, including packets
+that are dropped or requeued after being dequeued. The sojourn time is taken
+when the packet is dequeued from the queue disc, hence it does not account for
+the additional time the packet is retained within the queue disc in case it is
+requeued.
+
Design
==========
diff --git a/src/traffic-control/model/queue-disc.cc b/src/traffic-control/model/queue-disc.cc
index 575d93010..95f14b516 100644
--- a/src/traffic-control/model/queue-disc.cc
+++ b/src/traffic-control/model/queue-disc.cc
@@ -25,6 +25,7 @@
#include "ns3/packet.h"
#include "ns3/socket.h"
#include "ns3/unused.h"
+#include "ns3/simulator.h"
#include "queue-disc.h"
#include
#include "ns3/net-device-queue-interface.h"
@@ -192,6 +193,10 @@ TypeId QueueDisc::GetTypeId (void)
"Number of bytes currently stored in the queue disc",
MakeTraceSourceAccessor (&QueueDisc::m_nBytes),
"ns3::TracedValueCallback::Uint32")
+ .AddTraceSource ("SojournTime",
+ "Sojourn time of the last packet dequeued from the queue disc",
+ MakeTraceSourceAccessor (&QueueDisc::m_sojourn),
+ "ns3::Time::TracedValueCallback")
;
return tid;
}
@@ -199,6 +204,7 @@ TypeId QueueDisc::GetTypeId (void)
QueueDisc::QueueDisc ()
: m_nPackets (0),
m_nBytes (0),
+ m_sojourn (0),
m_running (false)
{
NS_LOG_FUNCTION (this);
@@ -435,6 +441,8 @@ QueueDisc::PacketDequeued (Ptr item)
m_stats.nTotalDequeuedPackets++;
m_stats.nTotalDequeuedBytes += item->GetSize ();
+ m_sojourn = Simulator::Now () - item->GetTimeStamp ();
+
NS_LOG_LOGIC ("m_traceDequeue (p)");
m_traceDequeue (item);
}
@@ -479,6 +487,11 @@ QueueDisc::Enqueue (Ptr item)
bool retval = DoEnqueue (item);
+ if (retval)
+ {
+ item->SetTimeStamp (Simulator::Now ());
+ }
+
// DoEnqueue may return false because:
// 1) the internal queue is full
// -> the DropBeforeEnqueue method of this queue disc is automatically called
diff --git a/src/traffic-control/model/queue-disc.h b/src/traffic-control/model/queue-disc.h
index 2b74f80dc..7763f891a 100644
--- a/src/traffic-control/model/queue-disc.h
+++ b/src/traffic-control/model/queue-disc.h
@@ -129,6 +129,13 @@ private:
* - queued = enqueued - dequeued
* - sent = dequeued - dropped after dequeue (- 1 if there is a requeued packet)
*
+ * The QueueDisc base class provides the SojournTime trace source, which provides
+ * the sojourn time of every packet dequeued from a queue disc, including packets
+ * that are dropped or requeued after being dequeued. The sojourn time is taken
+ * when the packet is dequeued from the queue disc, hence it does not account for
+ * the additional time the packet is retained within the queue disc in case it is
+ * requeued.
+ *
* The design and implementation of this class is heavily inspired by Linux.
* For more details, see the traffic-control model page.
*/
@@ -508,6 +515,7 @@ private:
TracedValue m_nPackets; //!< Number of packets in the queue
TracedValue m_nBytes; //!< Number of bytes in the queue
+ TracedValue