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:


    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