A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
prio-queue-disc.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 Universita' degli Studi di Napoli Federico II
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Stefano Avallone <stavallo@unina.it>
7 */
8
9#include "prio-queue-disc.h"
10
11#include "ns3/log.h"
12#include "ns3/object-factory.h"
13#include "ns3/pointer.h"
14#include "ns3/socket.h"
15
16#include <algorithm>
17#include <iterator>
18
19namespace ns3
20{
21
22NS_LOG_COMPONENT_DEFINE("PrioQueueDisc");
23
24NS_OBJECT_ENSURE_REGISTERED(PrioQueueDisc);
25
27
28std::ostream&
29operator<<(std::ostream& os, const Priomap& priomap)
30{
31 std::copy(priomap.begin(), priomap.end() - 1, std::ostream_iterator<uint16_t>(os, " "));
32 os << priomap.back();
33 return os;
34}
35
36std::istream&
37operator>>(std::istream& is, Priomap& priomap)
38{
39 for (int i = 0; i < 16; i++)
40 {
41 if (!(is >> priomap[i]))
42 {
43 NS_FATAL_ERROR("Incomplete priomap specification ("
44 << i << " values provided, 16 required)");
45 }
46 }
47 return is;
48}
49
50TypeId
52{
53 static TypeId tid =
54 TypeId("ns3::PrioQueueDisc")
56 .SetGroupName("TrafficControl")
57 .AddConstructor<PrioQueueDisc>()
58 .AddAttribute("Priomap",
59 "The priority to band mapping.",
60 PriomapValue(Priomap{{1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}}),
63 return tid;
64}
65
71
76
77void
78PrioQueueDisc::SetBandForPriority(uint8_t prio, uint16_t band)
79{
80 NS_LOG_FUNCTION(this << prio << band);
81
82 NS_ASSERT_MSG(prio < 16, "Priority must be a value between 0 and 15");
83
84 m_prio2band[prio] = band;
85}
86
87uint16_t
89{
90 NS_LOG_FUNCTION(this << prio);
91
92 NS_ASSERT_MSG(prio < 16, "Priority must be a value between 0 and 15");
93
94 return m_prio2band[prio];
95}
96
97bool
99{
100 NS_LOG_FUNCTION(this << item);
101
102 uint32_t band = m_prio2band[0];
103
104 int32_t ret = Classify(item);
105
106 if (ret == PacketFilter::PF_NO_MATCH)
107 {
108 NS_LOG_DEBUG("No filter has been able to classify this packet, using priomap.");
109
110 SocketPriorityTag priorityTag;
111 if (item->GetPacket()->PeekPacketTag(priorityTag))
112 {
113 band = m_prio2band[priorityTag.GetPriority() & 0x0f];
114 }
115 }
116 else
117 {
118 NS_LOG_DEBUG("Packet filters returned " << ret);
119
120 if (ret >= 0 && static_cast<uint32_t>(ret) < GetNQueueDiscClasses())
121 {
122 band = ret;
123 }
124 }
125
126 NS_ASSERT_MSG(band < GetNQueueDiscClasses(), "Selected band out of range");
127 bool retval = GetQueueDiscClass(band)->GetQueueDisc()->Enqueue(item);
128
129 // If Queue::Enqueue fails, QueueDisc::Drop is called by the child queue disc
130 // because QueueDisc::AddQueueDiscClass sets the drop callback
131
132 NS_LOG_LOGIC("Number packets band " << band << ": "
133 << GetQueueDiscClass(band)->GetQueueDisc()->GetNPackets());
134
135 return retval;
136}
137
140{
141 NS_LOG_FUNCTION(this);
142
144
145 for (uint32_t i = 0; i < GetNQueueDiscClasses(); i++)
146 {
147 if ((item = GetQueueDiscClass(i)->GetQueueDisc()->Dequeue()))
148 {
149 NS_LOG_LOGIC("Popped from band " << i << ": " << item);
150 NS_LOG_LOGIC("Number packets band "
151 << i << ": " << GetQueueDiscClass(i)->GetQueueDisc()->GetNPackets());
152 return item;
153 }
154 }
155
156 NS_LOG_LOGIC("Queue empty");
157 return item;
158}
159
162{
163 NS_LOG_FUNCTION(this);
164
166
167 for (uint32_t i = 0; i < GetNQueueDiscClasses(); i++)
168 {
169 if ((item = GetQueueDiscClass(i)->GetQueueDisc()->Peek()))
170 {
171 NS_LOG_LOGIC("Peeked from band " << i << ": " << item);
172 NS_LOG_LOGIC("Number packets band "
173 << i << ": " << GetQueueDiscClass(i)->GetQueueDisc()->GetNPackets());
174 return item;
175 }
176 }
177
178 NS_LOG_LOGIC("Queue empty");
179 return item;
180}
181
182bool
184{
185 NS_LOG_FUNCTION(this);
186 if (GetNInternalQueues() > 0)
187 {
188 NS_LOG_ERROR("PrioQueueDisc cannot have internal queues");
189 return false;
190 }
191
192 if (GetNQueueDiscClasses() == 0)
193 {
194 // create 3 fifo queue discs
195 ObjectFactory factory;
196 factory.SetTypeId("ns3::FifoQueueDisc");
197 for (uint8_t i = 0; i < 2; i++)
198 {
199 Ptr<QueueDisc> qd = factory.Create<QueueDisc>();
200 qd->Initialize();
202 c->SetQueueDisc(qd);
204 }
205 }
206
207 if (GetNQueueDiscClasses() < 2)
208 {
209 NS_LOG_ERROR("PrioQueueDisc needs at least 2 classes");
210 return false;
211 }
212
213 return true;
214}
215
216void
221
222} // namespace ns3
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
static const int PF_NO_MATCH
Standard value used by packet filters to indicate that no match was possible.
The Prio qdisc is a simple classful queueing discipline that contains an arbitrary number of classes ...
void SetBandForPriority(uint8_t prio, uint16_t band)
Set the band (class) assigned to packets with specified priority.
Ptr< const QueueDiscItem > DoPeek() override
Return a copy of the next packet the queue disc will extract.
Ptr< QueueDiscItem > DoDequeue() override
This function actually extracts a packet from the queue disc.
uint16_t GetBandForPriority(uint8_t prio) const
Get the band (class) assigned to packets with specified priority.
bool CheckConfig() override
Check whether the current configuration is correct.
PrioQueueDisc()
PrioQueueDisc constructor.
Priomap m_prio2band
Priority to band mapping.
bool DoEnqueue(Ptr< QueueDiscItem > item) override
This function actually enqueues a packet into the queue disc.
static TypeId GetTypeId()
Get the type ID.
void InitializeParams() override
Initialize parameters (if any) before the first packet is enqueued.
Smart pointer class similar to boost::intrusive_ptr.
QueueDisc is an abstract base class providing the interface and implementing the operations common to...
Definition queue-disc.h:173
void AddQueueDiscClass(Ptr< QueueDiscClass > qdClass)
Add a queue disc class to the tail of the list of classes.
uint32_t GetNPackets() const
Get the number of packets stored by the queue disc.
int32_t Classify(Ptr< QueueDiscItem > item)
Classify a packet by calling the packet filters, one at a time, until either a filter able to classif...
std::size_t GetNQueueDiscClasses() const
Get the number of queue disc classes.
Ptr< QueueDiscClass > GetQueueDiscClass(std::size_t i) const
Get the i-th queue disc class.
std::size_t GetNInternalQueues() const
Get the number of internal queues.
Ptr< QueueDiscItem > Dequeue()
Extract from the queue disc the packet that has been dequeued by calling Peek, if any,...
Ptr< const QueueDiscItem > Peek()
Get a copy of the next packet the queue discipline will extract.
indicates whether the socket has a priority set.
Definition socket.h:1307
uint8_t GetPriority() const
Get the tag's priority.
Definition socket.cc:849
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#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:75
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
QueueDiscSizePolicy
Enumeration of the available policies to handle the queue disc size.
Definition queue-disc.h:96
@ NO_LIMITS
Used by queue discs with unlimited size.
Definition queue-disc.h:100
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172
Ptr< const AttributeAccessor > MakePriomapAccessor(T1 a1)
std::array< uint16_t, 16 > Priomap
Priority map.
Ptr< const AttributeChecker > MakePriomapChecker()