A Discrete-Event Network Simulator
API
net-device-queue-interface.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Universita' degli Studi di Napoli Federico II
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Stefano Avallone <stefano.avallone@.unina.it>
18  */
19 #ifndef NET_DEVICE_QUEUE_INTERFACE_H
20 #define NET_DEVICE_QUEUE_INTERFACE_H
21 
22 #include "ns3/callback.h"
23 #include "ns3/log.h"
24 #include "ns3/net-device.h"
25 #include "ns3/object-factory.h"
26 #include "ns3/object.h"
27 #include "ns3/ptr.h"
28 #include "ns3/simulator.h"
29 
30 #include <functional>
31 #include <vector>
32 
33 namespace ns3
34 {
35 
36 class QueueLimits;
37 class NetDeviceQueueInterface;
38 class QueueItem;
39 
57 class NetDeviceQueue : public Object
58 {
59  public:
64  static TypeId GetTypeId();
65 
67  ~NetDeviceQueue() override;
68 
73  virtual void Start();
74 
79  virtual void Stop();
80 
86  virtual void Wake();
87 
95  virtual bool IsStopped() const;
96 
107 
110 
121  virtual void SetWakeCallback(WakeCallback cb);
122 
127  virtual void NotifyQueuedBytes(uint32_t bytes);
128 
133  virtual void NotifyTransmittedBytes(uint32_t bytes);
134 
138  void ResetQueueLimits();
139 
145 
151 
163  template <typename QueueType>
164  void PacketEnqueued(QueueType* queue, Ptr<const typename QueueType::ItemType> item);
165 
178  template <typename QueueType>
179  void PacketDequeued(QueueType* queue, Ptr<const typename QueueType::ItemType> item);
180 
193  template <typename QueueType>
194  void PacketDiscarded(QueueType* queue, Ptr<const typename QueueType::ItemType> item);
195 
204  template <typename QueueType>
206 
207  private:
213 
215 };
216 
231 {
232  public:
237  static TypeId GetTypeId();
238 
243  ~NetDeviceQueueInterface() override;
244 
253  Ptr<NetDeviceQueue> GetTxQueue(std::size_t i) const;
254 
259  std::size_t GetNTxQueues() const;
260 
270 
279  void SetNTxQueues(std::size_t numTxQueues);
280 
282  typedef std::function<std::size_t(Ptr<QueueItem>)> SelectQueueCallback;
283 
292 
301 
302  protected:
306  void DoDispose() override;
310  void NotifyNewAggregate() override;
311 
312  private:
314  std::vector<Ptr<NetDeviceQueue>> m_txQueuesVector;
316 };
317 
322 template <typename QueueType>
323 void
325 {
326  NS_ASSERT(queue);
327 
328  queue->TraceConnectWithoutContext(
329  "Enqueue",
330  MakeCallback(&NetDeviceQueue::PacketEnqueued<QueueType>, this).Bind(PeekPointer(queue)));
331  queue->TraceConnectWithoutContext(
332  "Dequeue",
333  MakeCallback(&NetDeviceQueue::PacketDequeued<QueueType>, this).Bind(PeekPointer(queue)));
334  queue->TraceConnectWithoutContext(
335  "DropBeforeEnqueue",
336  MakeCallback(&NetDeviceQueue::PacketDiscarded<QueueType>, this).Bind(PeekPointer(queue)));
337 }
338 
339 template <typename QueueType>
340 void
342 {
343  NS_LOG_FUNCTION(this << queue << item);
344 
345  // Inform BQL
346  NotifyQueuedBytes(item->GetSize());
347 
348  NS_ASSERT_MSG(m_device, "Aggregated NetDevice not set");
349  // After enqueuing a packet, we need to check whether the queue is able to
350  // store another packet. If not, we stop the queue
351 
352  if (queue->WouldOverflow(1, m_device->GetMtu()))
353  {
354  NS_LOG_DEBUG("The device queue is being stopped (" << queue->GetCurrentSize()
355  << " inside)");
356  Stop();
357  }
358 }
359 
360 template <typename QueueType>
361 void
363 {
364  NS_LOG_FUNCTION(this << queue << item);
365  NS_ASSERT_MSG(m_device, "Aggregated NetDevice not set");
366 
367  Simulator::ScheduleNow([=, this]() {
368  // Inform BQL
369  NotifyTransmittedBytes(item->GetSize());
370 
371  // After dequeuing a packet, if there is room for another packet we
372  // call Wake () that ensures that the queue is not stopped and restarts
373  // the queue disc if the queue was stopped
374 
375  if (!queue->WouldOverflow(1, m_device->GetMtu()))
376  {
377  Wake();
378  }
379  });
380 }
381 
382 template <typename QueueType>
383 void
385 {
386  NS_LOG_FUNCTION(this << queue << item);
387 
388  // This method is called when a packet is discarded before being enqueued in the
389  // device queue, likely because the queue is full. This should not happen if the
390  // device correctly stops the queue. Anyway, stop the tx queue, so that the upper
391  // layers do not send packets until there is room in the queue again.
392 
393  NS_LOG_ERROR("BUG! No room in the device queue for the received packet! ("
394  << queue->GetCurrentSize() << " inside)");
395 
396  Stop();
397 }
398 
399 } // namespace ns3
400 
401 #endif /* NET_DEVICE_QUEUE_INTERFACE_H */
Network device transmission queue.
bool m_stoppedByQueueLimits
True if the queue has been stopped by a queue limits object.
void ConnectQueueTraces(Ptr< QueueType > queue)
Connect the traced callbacks of a queue to the methods providing support for flow control and dynamic...
virtual void Stop()
Called by the device to stop this device transmission queue.
void NotifyAggregatedObject(Ptr< NetDeviceQueueInterface > ndqi)
Notify this NetDeviceQueue that the NetDeviceQueueInterface was aggregated to an object.
void PacketDiscarded(QueueType *queue, Ptr< const typename QueueType::ItemType > item)
Perform the actions required by flow control and dynamic queue limits when a packet is dropped before...
Ptr< QueueLimits > GetQueueLimits()
Get queue limits to this queue.
Ptr< QueueLimits > m_queueLimits
Queue limits object.
virtual void Wake()
Called by the device to wake the queue disc associated with this device transmission queue.
virtual bool IsStopped() const
Get the status of the device transmission queue.
void SetQueueLimits(Ptr< QueueLimits > ql)
Set queue limits to this queue.
NS_LOG_TEMPLATE_DECLARE
redefinition of the log component
void PacketDequeued(QueueType *queue, Ptr< const typename QueueType::ItemType > item)
Perform the actions required by flow control and dynamic queue limits when a packet is dequeued (or d...
void ResetQueueLimits()
Reset queue limits state.
virtual void Start()
Called by the device to start this device transmission queue.
virtual void NotifyTransmittedBytes(uint32_t bytes)
Called by the netdevice to report the number of bytes it is going to transmit.
virtual void NotifyQueuedBytes(uint32_t bytes)
Called by the netdevice to report the number of bytes queued to the device queue.
Ptr< NetDevice > m_device
the netdevice aggregated to the NetDeviceQueueInterface
WakeCallback m_wakeCallback
Wake callback.
Callback< void > WakeCallback
Callback invoked by netdevices to wake upper layers.
bool m_stoppedByDevice
True if the queue has been stopped by the device.
static TypeId GetTypeId()
Get the type ID.
virtual void SetWakeCallback(WakeCallback cb)
Set the wake callback.
void PacketEnqueued(QueueType *queue, Ptr< const typename QueueType::ItemType > item)
Perform the actions required by flow control and dynamic queue limits when a packet is enqueued in th...
Network device transmission queue interface.
SelectQueueCallback m_selectQueueCallback
Select queue callback.
std::vector< Ptr< NetDeviceQueue > > m_txQueuesVector
Device transmission queues.
std::size_t GetNTxQueues() const
Get the number of device transmission queues.
Ptr< NetDeviceQueue > GetTxQueue(std::size_t i) const
Get the i-th transmission queue of the device.
std::function< std::size_t(Ptr< QueueItem >)> SelectQueueCallback
Callback invoked to determine the tx queue selected for a given packet.
ObjectFactory m_txQueues
Device transmission queues TypeId.
void SetSelectQueueCallback(SelectQueueCallback cb)
Set the select queue callback.
void DoDispose() override
Dispose of the object.
SelectQueueCallback GetSelectQueueCallback() const
Get the select queue callback.
void SetTxQueuesType(TypeId type)
Set the type of device transmission queues to create.
void SetNTxQueues(std::size_t numTxQueues)
Set the number of device transmission queues to create.
void NotifyNewAggregate() override
Notify that an object was aggregated.
static TypeId GetTypeId()
Get the type ID.
Instantiate subclasses of ns3::Object.
A base class which provides memory management and object aggregation.
Definition: object.h:89
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
a unique identifier for an interface.
Definition: type-id.h:59
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
U * PeekPointer(const Ptr< U > &p)
Definition: ptr.h:449