A Discrete-Event Network Simulator
API
net-device-queue-interface.h
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2017 Universita' degli Studi di Napoli Federico II
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Stefano Avallone <stefano.avallone@.unina.it>
19  */
20 #ifndef NET_DEVICE_QUEUE_INTERFACE_H
21 #define NET_DEVICE_QUEUE_INTERFACE_H
22 
23 #include <vector>
24 #include <map>
25 #include "ns3/callback.h"
26 #include "ns3/object.h"
27 #include "ns3/ptr.h"
28 #include "ns3/queue-item.h"
29 #include "ns3/queue.h"
30 #include "ns3/net-device.h"
31 
32 namespace ns3 {
33 
34 class QueueLimits;
35 class NetDeviceQueueInterface;
36 
37 // This header file is included by all the queue discs and all the netdevices
38 // using a Queue object. The following explicit template instantiation
39 // declarations enables them to suppress implicit template instantiations
40 extern template class Queue<Packet>;
41 extern template class Queue<QueueDiscItem>;
42 
43 
62 {
63 public:
64  NetDeviceQueue ();
65  virtual ~NetDeviceQueue();
66 
71  virtual void Start (void);
72 
77  virtual void Stop (void);
78 
84  virtual void Wake (void);
85 
93  bool IsStopped (void) const;
94 
97 
108  virtual void SetWakeCallback (WakeCallback cb);
109 
114  void NotifyQueuedBytes (uint32_t bytes);
115 
120  void NotifyTransmittedBytes (uint32_t bytes);
121 
125  void ResetQueueLimits ();
126 
131  void SetQueueLimits (Ptr<QueueLimits> ql);
132 
137  Ptr<QueueLimits> GetQueueLimits ();
138 
152  template <typename Item>
153  static void PacketEnqueued (Ptr<Queue<Item> > queue,
155  uint8_t txq, Ptr<const Item> item);
156 
171  template <typename Item>
172  static void PacketDequeued (Ptr<Queue<Item> > queue,
174  uint8_t txq, Ptr<const Item> item);
175 
190  template <typename Item>
191  static void PacketDiscarded (Ptr<Queue<Item> > queue,
193  uint8_t txq, Ptr<const Item> item);
194 
195 private:
199  WakeCallback m_wakeCallback;
200 };
201 
202 
219 {
220 public:
225  static TypeId GetTypeId (void);
226 
233  virtual ~NetDeviceQueueInterface ();
234 
243  Ptr<NetDeviceQueue> GetTxQueue (uint8_t i) const;
244 
249  uint8_t GetNTxQueues (void) const;
250 
259  void SetTxQueuesN (uint8_t numTxQueues);
260 
267  void CreateTxQueues (void);
268 
273  bool GetLateTxQueuesCreation (void) const;
274 
285  void SetLateTxQueuesCreation (bool value);
286 
289 
298  void SetSelectQueueCallback (SelectQueueCallback cb);
299 
307  SelectQueueCallback GetSelectQueueCallback (void) const;
308 
315  template <typename Item>
316  void ConnectQueueTraces (Ptr<Queue<Item> > queue, uint8_t txq);
317 
318 protected:
322  virtual void DoDispose (void);
323 
324 private:
325  std::vector< Ptr<NetDeviceQueue> > m_txQueuesVector;
326  SelectQueueCallback m_selectQueueCallback;
327  uint8_t m_numTxQueues;
329  std::map<Ptr<QueueBase>, std::vector<CallbackBase> > m_traceMap;
330 };
331 
332 
337 template <typename Item>
338 void
340 {
341  NS_ASSERT (queue != 0);
342  NS_ASSERT (txq < GetNTxQueues ());
343 
344  m_traceMap.emplace (queue, std::initializer_list<CallbackBase> {
345  MakeBoundCallback (&NetDeviceQueue::PacketEnqueued<Item>, queue, this, txq),
346  MakeBoundCallback (&NetDeviceQueue::PacketDequeued<Item>, queue, this, txq),
347  MakeBoundCallback (&NetDeviceQueue::PacketDiscarded<Item>, queue, this, txq) });
348 
349  queue->TraceConnectWithoutContext ("Enqueue", m_traceMap[queue][0]);
350  queue->TraceConnectWithoutContext ("Dequeue", m_traceMap[queue][1]);
351  queue->TraceConnectWithoutContext ("DropAfterDequeue", m_traceMap[queue][1]);
352  queue->TraceConnectWithoutContext ("DropBeforeEnqueue", m_traceMap[queue][2]);
353 }
354 
355 template <typename Item>
356 void
359  uint8_t txq, Ptr<const Item> item)
360 {
361  NS_LOG_STATIC_TEMPLATE_DEFINE ("NetDeviceQueueInterface");
362 
363  NS_LOG_FUNCTION (queue << ndqi << txq << item);
364 
365  // Inform BQL
366  ndqi->GetTxQueue (txq)->NotifyQueuedBytes (item->GetSize ());
367 
368  uint16_t mtu = ndqi->GetObject<NetDevice> ()->GetMtu ();
369 
370  // After enqueuing a packet, we need to check whether the queue is able to
371  // store another packet. If not, we stop the queue
372 
373  if ((queue->GetMode () == QueueBase::QUEUE_MODE_PACKETS &&
374  queue->GetNPackets () >= queue->GetMaxPackets ()) ||
375  (queue->GetMode () == QueueBase::QUEUE_MODE_BYTES &&
376  queue->GetNBytes () + mtu > queue->GetMaxBytes ()))
377  {
378  NS_LOG_DEBUG ("The device queue is being stopped (" << queue->GetNPackets ()
379  << " packets and " << queue->GetNBytes () << " bytes inside)");
380  ndqi->GetTxQueue (txq)->Stop ();
381  }
382 }
383 
384 template <typename Item>
385 void
388  uint8_t txq, Ptr<const Item> item)
389 {
390  NS_LOG_STATIC_TEMPLATE_DEFINE ("NetDeviceQueueInterface");
391 
392  NS_LOG_FUNCTION (queue << ndqi << txq << item);
393 
394  // Inform BQL
395  ndqi->GetTxQueue (txq)->NotifyTransmittedBytes (item->GetSize ());
396 
397  uint16_t mtu = ndqi->GetObject<NetDevice> ()->GetMtu ();
398 
399  // After dequeuing a packet, if there is room for another packet we
400  // call Wake () that ensures that the queue is not stopped and restarts
401  // the queue disc if the queue was stopped
402 
403  if ((queue->GetMode () == QueueBase::QUEUE_MODE_PACKETS &&
404  queue->GetNPackets () < queue->GetMaxPackets ()) ||
405  (queue->GetMode () == QueueBase::QUEUE_MODE_BYTES &&
406  queue->GetNBytes () + mtu <= queue->GetMaxBytes ()))
407  {
408  ndqi->GetTxQueue (txq)->Wake ();
409  }
410 }
411 
412 template <typename Item>
413 void
416  uint8_t txq, Ptr<const Item> item)
417 {
418  NS_LOG_STATIC_TEMPLATE_DEFINE ("NetDeviceQueueInterface");
419 
420  NS_LOG_FUNCTION (queue << ndqi << txq << item);
421 
422  // This method is called when a packet is discarded before being enqueued in the
423  // device queue, likely because the queue is full. This should not happen if the
424  // device correctly stops the queue. Anyway, stop the tx queue, so that the upper
425  // layers do not send packets until there is room in the queue again.
426 
427  NS_LOG_ERROR ("BUG! No room in the device queue for the received packet! ("
428  << queue->GetNPackets () << " packets and " << queue->GetNBytes () << " bytes inside)");
429 
430  ndqi->GetTxQueue (txq)->Stop ();
431 }
432 
433 } // namespace ns3
434 
435 #endif /* NET_DEVICE_QUEUE_INTERFACE_H */
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint8_t GetNTxQueues(void) const
Get the number of device transmission queues.
std::map< Ptr< QueueBase >, std::vector< CallbackBase > > m_traceMap
Map storing all the connected traces.
bool m_stoppedByDevice
True if the queue has been stopped by the device.
bool m_stoppedByQueueLimits
True if the queue has been stopped by a queue limits object.
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1686
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
WakeCallback m_wakeCallback
Wake callback.
static void PacketDequeued(Ptr< Queue< Item > > queue, Ptr< NetDeviceQueueInterface > ndqi, uint8_t txq, Ptr< const Item > item)
Perform the actions required by flow control and dynamic queue limits when a packet is dequeued (or d...
static void PacketEnqueued(Ptr< Queue< Item > > queue, Ptr< NetDeviceQueueInterface > ndqi, uint8_t txq, Ptr< const Item > item)
Perform the actions required by flow control and dynamic queue limits when a packet is enqueued in th...
Use number of packets for maximum queue size.
Definition: queue.h:166
Template class for packet Queues.
Callback< void > WakeCallback
Callback invoked by netdevices to wake upper layers.
Callback< uint8_t, Ptr< QueueItem > > SelectQueueCallback
Callback invoked to determine the tx queue selected for a given packet.
void ConnectQueueTraces(Ptr< Queue< Item > > queue, uint8_t txq)
Connect the traced callbacks of a queue to the static methods of the NetDeviceQueue class to support ...
#define NS_LOG_STATIC_TEMPLATE_DEFINE(name)
Declare and initialize a reference to a Log component.
Definition: log.h:245
SelectQueueCallback m_selectQueueCallback
Select queue callback.
Network device transmission queue interface.
uint8_t m_numTxQueues
Number of transmission queues to create.
bool m_lateTxQueuesCreation
True if a device wants to create the TX queues by itself.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::vector< Ptr< NetDeviceQueue > > m_txQueuesVector
Device transmission queues.
Use number of bytes for maximum queue size.
Definition: queue.h:167
Ptr< QueueLimits > m_queueLimits
Queue limits object.
Network layer to device interface.
Definition: net-device.h:95
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:269
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:253
A base class which provides memory management and object aggregation.
Definition: object.h:87
Network device transmission queue.
a unique identifier for an interface.
Definition: type-id.h:58
static void PacketDiscarded(Ptr< Queue< Item > > queue, Ptr< NetDeviceQueueInterface > ndqi, uint8_t txq, Ptr< const Item > item)
Perform the actions required by flow control and dynamic queue limits when a packet is dropped before...