diff --git a/CHANGES.html b/CHANGES.html
index f46d3e29e..ea6f7f92b 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -101,6 +101,10 @@ us a note on ns-developers mailing list.
Abstract base class WifiChannel has been removed. As a result, a Channel type instead of a WifiChannel type
is now exported by WifiNetDevice.
+ The GetPacketSize method of QueueItem has been renamed GetSize
+
+ The DequeueAll method of Queue has been renamed Flush
+
Changes to build system:
@@ -126,6 +130,22 @@ is now exported by WifiNetDevice.
- The default value of the TxGain and RxGain attributes in WifiPhy was changed from 1 dB to 0 dB.
+- Queue has been redesigned as a template class object, where the type parameter
+ specifies the type of items to be stored in the queue. As a consequence:
+
+ - Being a subclass of Queue, DropTailQueue is a template class as well.
+
- Network devices such as SimpleNetDevice, PointToPointNetDevice and CsmaNetDevice
+ use a queue of type Queue<Packet> to store the packets to transmit. The SetQueue
+ method of their helpers, however, can still be invoked as, e.g.,
+ SetQueue ("ns3::DropTailQueue") instead of, e.g., SetQueue
+ ("ns3::DropTailQueue<Packet>").
+ - The attributes Mode, MaxPackets and MaxBytes are now
+ defined by the QueueBase class (which Queue is derived from).
+
+
+- Queue discs that can operate both in packet mode and byte mode (Red, CoDel, Pie) define their own
+ enum QueueDiscMode instead of using QueueBase::QueueMode.
+
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 2c03cac37..ad80564ed 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -24,6 +24,7 @@ New user-visible features
- (wifi) 802.11ax High Efficiency (HE) physical layer modes are now supported.
- (tcp) The SACK option and the RFC 6675 loss recovery algorithm are now supported.
- (lte) LTE carrier aggregation feature according to 3GPP Release 10 is now supported.
+- (network) CsmaNetDevice, SimpleNetDevice and WifiNetDevice support flow control.
Bugs fixed
----------
diff --git a/src/network/doc/queue.rst b/src/network/doc/queue.rst
index a259870c3..81de9db5c 100644
--- a/src/network/doc/queue.rst
+++ b/src/network/doc/queue.rst
@@ -11,56 +11,73 @@ This section documents the queue object, which is typically used by NetDevices
and QueueDiscs to store packets.
Packets stored in a queue can be managed according to different policies.
-Currently, the following policies are available:
-
-* DropTail
+Currently, only the DropTail policy is available.
Model Description
*****************
The source code for the new module lives in the directory ``src/network/utils``.
-ns-3 provides the classic droptail queue model and the ability to
-trace certain queue operations such as enqueuing, dequeuing, and dropping.
-These may be added to certain NetDevice objects that take a Ptr
-pointer.
+ns3::Queue has been redesigned as a template class object to allow us to
+instantiate queues storing different types of items. The unique template
+type parameter specifies the type of items stored in the queue.
+The only requirement on the item type is that it must provide a GetSize ()
+method which returns the size of the packet included in the item.
+Currently, queue items can be objects of the following classes:
-Note that not all device models use these queue models.
-In particular, WiFi, WiMax, and LTE use specialized device queues.
-The queue models described here are more often used with simpler ns-3
-device models such as PointToPoint and Csma.
+* Packet
+* QueueItem and subclasses (e.g., QueueDiscItem)
+* WifiMacQueueItem
-All the queuing disciplines, instead, make use of the queue model defined here.
+The internal queues of the queue discs are of type Queue
+(an alias of which being InternalQueue). A number of network devices
+(SimpleNetDevice, PointToPointNetDevice, CsmaNetDevice) use a Queue
+to store packets to be transmitted. WifiNetDevices use instead queues of
+type WifiMacQueue, which is a subclass of Queue storing objects of
+type WifiMacQueueItem. Other devices, such as WiMax and LTE, use specialized
+queues.
Design
======
-An abstract base class, class Queue, is typically used and subclassed
-for specific scheduling and drop policies. A class QueueItem is introduced
-to model the items stored in a queue. The base class QueueItem only contains
-a pointer to a packet. Subclasses may be defined to store additional information.
-Common operations provided by the base class Queue include:
+The Queue class derives from the QueueBase class, which is a non-template
+class providing all the methods that are independent of the type of the items
+stored in the queue. The Queue class provides instead all the operations that
+depend on the item type, such as enqueue, dequeue, peek and remove. The Queue
+class also provides the ability to trace certain queue operations such as
+enqueuing, dequeuing, and dropping.
-* ``bool Enqueue (Ptr item)``: Enqueue a packet
-* ``Ptr Dequeue (void)``: Dequeue a packet
-* ``uint32_t GetNPackets (void)``: Get the queue depth, in packets
-* ``uint32_t GetNBytes (void)``: Get the queue depth, in packets
+Queue is an abstract base class and is subclassed for specific scheduling and
+drop policies. Subclasses need to define the following public methods:
-as well as tracking some statistics on queue operations.
+* ``bool Enqueue (Ptr- item)``: Enqueue a packet
+* ``Ptr
- Dequeue (void)``: Dequeue a packet
+* ``Ptr
- Remove (void)``: Remove a packet
+* ``Ptr Peek (void)``: Peek a packet
-There are three trace sources that may be hooked:
+The Enqueue method does not allow to store a packet if the queue capacity is exceeded.
+Subclasses may also define specialized public methods. For instance, the
+WifiMacQueue class provides a method to dequeue a packet based on its tid
+and MAC address.
+
+There are five trace sources that may be hooked:
* ``Enqueue``
* ``Dequeue``
* ``Drop``
+* ``DropBeforeEnqueue``
+* ``DropAfterDequeue``
-Also, three attributes are defined in the Queue base class:
+Also, the QueueBase class defines three attributes:
* ``Mode``: whether the capacity of the queue is measured in packets or bytes
* ``MaxPackets``: the maximum number of packets accepted by the queue in packet mode
* ``MaxBytes``: the maximum number of bytes accepted by the queue in byte mode
-The Enqueue method does not allow to store a packet if the queue capacity is exceeded.
+and two trace sources:
+
+* ``PacketsInQueue``
+* ``BytesInQueue``
DropTail
########
@@ -98,6 +115,9 @@ the queue type and attributes from the helper, such as this example:
p2p.SetChannelAttribute ("Delay", StringValue (linkDelay));
NetDeviceContainer devn2n3 = p2p.Install (n2n3);
+Please note that the SetQueue method of the PointToPointHelper class allows
+to specify "ns3::DropTailQueue" instead of "ns3::DropTailQueue". The
+same holds for CsmaHelper, SimpleNetDeviceHelper and TrafficControlHelper.
Output
======
diff --git a/src/network/utils/drop-tail-queue.h b/src/network/utils/drop-tail-queue.h
index 2c2484ef5..51d65a9ec 100644
--- a/src/network/utils/drop-tail-queue.h
+++ b/src/network/utils/drop-tail-queue.h
@@ -19,7 +19,6 @@
#ifndef DROPTAIL_H
#define DROPTAIL_H
-#include
#include "ns3/queue.h"
namespace ns3 {
@@ -47,13 +46,18 @@ public:
virtual ~DropTailQueue ();
-private:
- virtual bool DoEnqueue (Ptr
- item);
- virtual Ptr
- DoDequeue (void);
- virtual Ptr
- DoRemove (void);
- virtual Ptr DoPeek (void) const;
+ virtual bool Enqueue (Ptr
- item);
+ virtual Ptr
- Dequeue (void);
+ virtual Ptr
- Remove (void);
+ virtual Ptr Peek (void) const;
- std::queue > m_packets; //!< the items in the queue
+private:
+ using Queue
- ::Head;
+ using Queue
- ::Tail;
+ using Queue
- ::DoEnqueue;
+ using Queue
- ::DoDequeue;
+ using Queue
- ::DoRemove;
+ using Queue
- ::DoPeek;
};
@@ -75,8 +79,7 @@ DropTailQueue
- ::GetTypeId (void)
template
DropTailQueue
- ::DropTailQueue () :
- Queue
- (),
- m_packets ()
+ Queue
- ()
{
QUEUE_LOG (LOG_LOGIC, "DropTailQueue(" << this << ")");
}
@@ -89,25 +92,20 @@ DropTailQueue
- ::~DropTailQueue ()
template
bool
-DropTailQueue
- ::DoEnqueue (Ptr
- item)
+DropTailQueue
- ::Enqueue (Ptr
- item)
{
- QUEUE_LOG (LOG_LOGIC, "DropTailQueue:DoEnqueue(" << this << ", " << item << ")");
- NS_ASSERT (m_packets.size () == this->GetNPackets ());
+ QUEUE_LOG (LOG_LOGIC, "DropTailQueue:Enqueue(" << this << ", " << item << ")");
- m_packets.push (item);
-
- return true;
+ return DoEnqueue (Tail (), item);
}
template
Ptr
-
-DropTailQueue
- ::DoDequeue (void)
+DropTailQueue
- ::Dequeue (void)
{
- QUEUE_LOG (LOG_LOGIC, "DropTailQueue:DoDequeue(" << this << ")");
- NS_ASSERT (m_packets.size () == this->GetNPackets ());
+ QUEUE_LOG (LOG_LOGIC, "DropTailQueue:Dequeue(" << this << ")");
- Ptr
- item = m_packets.front ();
- m_packets.pop ();
+ Ptr
- item = DoDequeue (Head ());
QUEUE_LOG (LOG_LOGIC, "Popped " << item);
@@ -116,13 +114,11 @@ DropTailQueue
- ::DoDequeue (void)
template
Ptr
-
-DropTailQueue
- ::DoRemove (void)
+DropTailQueue
- ::Remove (void)
{
- QUEUE_LOG (LOG_LOGIC, "DropTailQueue:DoRemove(" << this << ")");
- NS_ASSERT (m_packets.size () == this->GetNPackets ());
+ QUEUE_LOG (LOG_LOGIC, "DropTailQueue:Remove(" << this << ")");
- Ptr
- item = m_packets.front ();
- m_packets.pop ();
+ Ptr
- item = DoRemove (Head ());
QUEUE_LOG (LOG_LOGIC, "Removed " << item);
@@ -131,12 +127,11 @@ DropTailQueue
- ::DoRemove (void)
template
Ptr
-DropTailQueue
- ::DoPeek (void) const
+DropTailQueue
- ::Peek (void) const
{
- QUEUE_LOG (LOG_LOGIC, "DropTailQueue:DoPeek(" << this << ")");
- NS_ASSERT (m_packets.size () == this->GetNPackets ());
+ QUEUE_LOG (LOG_LOGIC, "DropTailQueue:Peek(" << this << ")");
- return m_packets.front ();
+ return DoPeek (Head ());
}
} // namespace ns3
diff --git a/src/network/utils/queue.h b/src/network/utils/queue.h
index e809a02cd..c285672ab 100644
--- a/src/network/utils/queue.h
+++ b/src/network/utils/queue.h
@@ -31,6 +31,7 @@
#include "ns3/log.h"
#include
#include
+#include
namespace ns3 {
@@ -295,29 +296,32 @@ public:
virtual ~Queue ();
/**
- * Place a queue item into the rear of the Queue
+ * Place an item into the Queue (each subclass defines the position)
* \param item item to enqueue
* \return True if the operation was successful; false otherwise
*/
- bool Enqueue (Ptr- item);
+ virtual bool Enqueue (Ptr
- item) = 0;
/**
- * Remove an item from the front of the Queue, counting it as dequeued
+ * Remove an item from the Queue (each subclass defines the position),
+ * counting it as dequeued
* \return 0 if the operation was not successful; the item otherwise.
*/
- Ptr
- Dequeue (void);
+ virtual Ptr
- Dequeue (void) = 0;
/**
- * Remove an item from the front of the Queue, counting it as dropped
+ * Remove an item from the Queue (each subclass defines the position),
+ * counting it as dropped
* \return 0 if the operation was not successful; the item otherwise.
*/
- Ptr
- Remove (void);
+ virtual Ptr
- Remove (void) = 0;
/**
- * Get a copy of the item at the front of the queue without removing it
+ * Get a copy of an item in the queue (each subclass defines the position)
+ * without removing it
* \return 0 if the operation was not successful; the item otherwise.
*/
- Ptr Peek (void) const;
+ virtual Ptr Peek (void) const = 0;
/**
* Flush the queue.
@@ -325,6 +329,70 @@ public:
void Flush (void);
protected:
+
+ typedef typename std::list >::const_iterator ConstIterator;
+
+ /**
+ * \brief Get a const iterator which refers to the first item in the queue.
+ *
+ * Subclasses can browse the items in the queue by using an iterator
+ *
+ * \code
+ * for (auto i = Head (); i != Tail (); ++i)
+ * {
+ * (*i)->method (); // some method of the Item class
+ * }
+ * \endcode
+ *
+ * \returns a const iterator which refers to the first item in the queue.
+ */
+ ConstIterator Head (void) const;
+
+ /**
+ * \brief Get a const iterator which indicates past-the-last item in the queue.
+ *
+ * Subclasses can browse the items in the queue by using an iterator
+ *
+ * \code
+ * for (auto i = Head (); i != Tail (); ++i)
+ * {
+ * (*i)->method (); // some method of the Item class
+ * }
+ * \endcode
+ *
+ * \returns a const iterator which indicates past-the-last item in the queue.
+ */
+ ConstIterator Tail (void) const;
+
+ /**
+ * Push an item in the queue
+ * \param pos the position where the item is inserted
+ * \param item the item to enqueue
+ * \return true if success, false if the packet has been dropped.
+ */
+ bool DoEnqueue (ConstIterator pos, Ptr
- item);
+
+ /**
+ * Pull the item to dequeue from the queue
+ * \param pos the position of the item to dequeue
+ * \return the item.
+ */
+ Ptr
- DoDequeue (ConstIterator pos);
+
+ /**
+ * Pull the item to drop from the queue
+ * \param pos the position of the item to remove
+ * \return the item.
+ */
+ Ptr
- DoRemove (ConstIterator pos);
+
+ /**
+ * Peek the front item in the queue
+ * \param pos the position of the item to peek
+ * \return the item.
+ */
+ Ptr DoPeek (ConstIterator pos) const;
+
/**
* \brief Drop a packet before enqueue
* \param item item that was dropped
@@ -346,32 +414,8 @@ protected:
void DropAfterDequeue (Ptr
- item);
private:
- /**
- * Push an item in the queue
- * \param item the item to enqueue
- * \return true if success, false if the packet has been dropped.
- */
- virtual bool DoEnqueue (Ptr
- item) = 0;
+ std::list > m_packets; //!< the items in the queue
- /**
- * Pull the item to dequeue from the queue
- * \return the item.
- */
- virtual Ptr
- DoDequeue (void) = 0;
-
- /**
- * Pull the item to drop from the queue
- * \return the item.
- */
- virtual Ptr
- DoRemove (void) = 0;
-
- /**
- * Peek the front item in the queue
- * \return the item.
- */
- virtual Ptr DoPeek (void) const = 0;
-
-private:
/// Traced callback: fired when a packet is enqueued
TracedCallback > m_traceEnqueue;
/// Traced callback: fired when a packet is dequeued
@@ -436,9 +480,9 @@ Queue
- ::~Queue ()
template
bool
-Queue
- ::Enqueue (Ptr
- item)
+Queue
- ::DoEnqueue (ConstIterator pos, Ptr
- item)
{
- QUEUE_LOG (LOG_LOGIC, "Queue:Enqueue(" << this << ", " << item << ")");
+ QUEUE_LOG (LOG_LOGIC, "Queue:DoEnqueue(" << this << ", " << item << ")");
if (m_mode == QUEUE_MODE_PACKETS && (m_nPackets.Get () >= m_maxPackets))
{
@@ -454,30 +498,26 @@ Queue
- ::Enqueue (Ptr
- item)
return false;
}
- //
- // If DoEnqueue fails, Queue::DropBeforeEnqueue is called by the subclass
- //
- bool retval = DoEnqueue (item);
- if (retval)
- {
- uint32_t size = item->GetSize ();
- m_nBytes += size;
- m_nTotalReceivedBytes += size;
+ m_packets.insert (pos, item);
- m_nPackets++;
- m_nTotalReceivedPackets++;
+ uint32_t size = item->GetSize ();
+ m_nBytes += size;
+ m_nTotalReceivedBytes += size;
- QUEUE_LOG (LOG_LOGIC, "m_traceEnqueue (p)");
- m_traceEnqueue (item);
- }
- return retval;
+ m_nPackets++;
+ m_nTotalReceivedPackets++;
+
+ QUEUE_LOG (LOG_LOGIC, "m_traceEnqueue (p)");
+ m_traceEnqueue (item);
+
+ return true;
}
template
Ptr
-
-Queue
- ::Dequeue (void)
+Queue
- ::DoDequeue (ConstIterator pos)
{
- QUEUE_LOG (LOG_LOGIC, "Queue:Dequeue(" << this << ")");
+ QUEUE_LOG (LOG_LOGIC, "Queue:DoDequeue(" << this << ")");
if (m_nPackets.Get () == 0)
{
@@ -485,7 +525,8 @@ Queue
- ::Dequeue (void)
return 0;
}
- Ptr
- item = DoDequeue ();
+ Ptr
- item = *pos;
+ m_packets.erase (pos);
if (item != 0)
{
@@ -503,9 +544,9 @@ Queue
- ::Dequeue (void)
template
Ptr
-
-Queue
- ::Remove (void)
+Queue
- ::DoRemove (ConstIterator pos)
{
- QUEUE_LOG (LOG_LOGIC, "Queue:Remove(" << this << ")");
+ QUEUE_LOG (LOG_LOGIC, "Queue:DoRemove(" << this << ")");
if (m_nPackets.Get () == 0)
{
@@ -513,7 +554,8 @@ Queue
- ::Remove (void)
return 0;
}
- Ptr
- item = DoRemove ();
+ Ptr
- item = *pos;
+ m_packets.erase (pos);
if (item != 0)
{
@@ -541,9 +583,9 @@ Queue
- ::Flush (void)
template
Ptr
-Queue
- ::Peek (void) const
+Queue
- ::DoPeek (ConstIterator pos) const
{
- QUEUE_LOG (LOG_LOGIC, "Queue:Peek(" << this << ")");
+ QUEUE_LOG (LOG_LOGIC, "Queue:DoPeek(" << this << ")");
if (m_nPackets.Get () == 0)
{
@@ -551,7 +593,19 @@ Queue
- ::Peek (void) const
return 0;
}
- return DoPeek ();
+ return *pos;
+}
+
+template
+typename Queue
- ::ConstIterator Queue
- ::Head (void) const
+{
+ return m_packets.cbegin ();
+}
+
+template
+typename Queue
- ::ConstIterator Queue
- ::Tail (void) const
+{
+ return m_packets.cend ();
}
template