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:
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;
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  Ptr<Packet> p = Create<Packet> (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->GetCurrentSize () + p > queue->GetMaxSize ())
374  {
375  NS_LOG_DEBUG ("The device queue is being stopped (" << queue->GetNPackets ()
376  << " packets and " << queue->GetNBytes () << " bytes inside)");
377  ndqi->GetTxQueue (txq)->Stop ();
378  }
379 }
380 
381 template <typename Item>
382 void
385  uint8_t txq, Ptr<const Item> item)
386 {
387  NS_LOG_STATIC_TEMPLATE_DEFINE ("NetDeviceQueueInterface");
388 
389  NS_LOG_FUNCTION (queue << ndqi << txq << item);
390 
391  // Inform BQL
392  ndqi->GetTxQueue (txq)->NotifyTransmittedBytes (item->GetSize ());
393 
394  Ptr<Packet> p = Create<Packet> (ndqi->GetObject<NetDevice> ()->GetMtu ());
395 
396  // After dequeuing a packet, if there is room for another packet we
397  // call Wake () that ensures that the queue is not stopped and restarts
398  // the queue disc if the queue was stopped
399 
400  if (queue->GetCurrentSize () + p <= queue->GetMaxSize ())
401  {
402  ndqi->GetTxQueue (txq)->Wake ();
403  }
404 }
405 
406 template <typename Item>
407 void
410  uint8_t txq, Ptr<const Item> item)
411 {
412  NS_LOG_STATIC_TEMPLATE_DEFINE ("NetDeviceQueueInterface");
413 
414  NS_LOG_FUNCTION (queue << ndqi << txq << item);
415 
416  // This method is called when a packet is discarded before being enqueued in the
417  // device queue, likely because the queue is full. This should not happen if the
418  // device correctly stops the queue. Anyway, stop the tx queue, so that the upper
419  // layers do not send packets until there is room in the queue again.
420 
421  NS_LOG_ERROR ("BUG! No room in the device queue for the received packet! ("
422  << queue->GetNPackets () << " packets and " << queue->GetNBytes () << " bytes inside)");
423 
424  ndqi->GetTxQueue (txq)->Stop ();
425 }
426 
427 } // namespace ns3
428 
429 #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 "...
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...
uint8_t GetNTxQueues(void) const
Get the number of device transmission queues.
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...
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:246
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.
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:270
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
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...