A Discrete-Event Network Simulator
API
fcfs-wifi-queue-scheduler.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2022 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 <stavallo@unina.it>
18  */
19 
21 
22 #include "wifi-mac-queue.h"
23 
24 #include "ns3/enum.h"
25 #include "ns3/log.h"
26 
27 namespace ns3
28 {
29 
30 NS_LOG_COMPONENT_DEFINE("FcfsWifiQueueScheduler");
31 
32 bool
33 operator==(const FcfsPrio& lhs, const FcfsPrio& rhs)
34 {
35  return lhs.priority == rhs.priority && lhs.type == rhs.type;
36 }
37 
38 bool
39 operator<(const FcfsPrio& lhs, const FcfsPrio& rhs)
40 {
41  // Control queues have the highest priority
42  if (lhs.type == WIFI_CTL_QUEUE && rhs.type != WIFI_CTL_QUEUE)
43  {
44  return true;
45  }
46  if (lhs.type != WIFI_CTL_QUEUE && rhs.type == WIFI_CTL_QUEUE)
47  {
48  return false;
49  }
50  // Management queues have the second highest priority
51  if (lhs.type == WIFI_MGT_QUEUE && rhs.type != WIFI_MGT_QUEUE)
52  {
53  return true;
54  }
55  if (lhs.type != WIFI_MGT_QUEUE && rhs.type == WIFI_MGT_QUEUE)
56  {
57  return false;
58  }
59  // we get here if both priority values refer to container queues of the same type,
60  // hence we can compare the time values.
61  return lhs.priority < rhs.priority;
62 }
63 
64 NS_OBJECT_ENSURE_REGISTERED(FcfsWifiQueueScheduler);
65 
66 TypeId
68 {
69  static TypeId tid = TypeId("ns3::FcfsWifiQueueScheduler")
71  .SetGroupName("Wifi")
72  .AddConstructor<FcfsWifiQueueScheduler>()
73  .AddAttribute("DropPolicy",
74  "Upon enqueue with full queue, drop oldest (DropOldest) "
75  "or newest (DropNewest) packet",
79  "DropOldest",
81  "DropNewest"));
82  return tid;
83 }
84 
86  : NS_LOG_TEMPLATE_DEFINE("FcfsWifiQueueScheduler")
87 {
88 }
89 
92 {
93  auto queue = GetWifiMacQueue(ac);
94  if (queue->QueueBase::GetNPackets() < queue->GetMaxSize().GetValue())
95  {
96  // the queue is not full, do not drop anything
97  return nullptr;
98  }
99 
100  // Control and management frames should be prioritized
101  if (m_dropPolicy == DROP_OLDEST || mpdu->GetHeader().IsCtl() || mpdu->GetHeader().IsMgt())
102  {
103  for (const auto& [priority, queueInfo] : GetSortedQueues(ac))
104  {
105  if (std::get<WifiContainerQueueType>(queueInfo.get().first) == WIFI_MGT_QUEUE ||
106  std::get<WifiContainerQueueType>(queueInfo.get().first) == WIFI_CTL_QUEUE)
107  {
108  // do not drop control or management frames
109  continue;
110  }
111 
112  // do not drop frames that are inflight or to be retransmitted
113  Ptr<WifiMpdu> item;
114  while ((item = queue->PeekByQueueId(queueInfo.get().first, item)))
115  {
116  if (!item->IsInFlight() && !item->GetHeader().IsRetry())
117  {
118  NS_LOG_DEBUG("Dropping " << *item);
119  return item;
120  }
121  }
122  }
123  }
124  NS_LOG_DEBUG("Dropping received MPDU: " << *mpdu);
125  return mpdu;
126 }
127 
128 void
130 {
131  NS_LOG_FUNCTION(this << +ac << *mpdu);
132 
133  const auto queueId = WifiMacQueueContainer::GetQueueId(mpdu);
134 
135  if (GetWifiMacQueue(ac)->GetNPackets(queueId) > 1)
136  {
137  // Enqueue takes place at the tail, while the priority is determined by the
138  // head of the queue. Therefore, if the queue was not empty before inserting
139  // this MPDU, priority does not change
140  return;
141  }
142 
143  SetPriority(ac, queueId, {mpdu->GetExpiryTime(), std::get<WifiContainerQueueType>(queueId)});
144 }
145 
146 void
148 {
149  NS_LOG_FUNCTION(this << +ac << mpdus.size());
150 
151  std::set<WifiContainerQueueId> queueIds;
152 
153  for (const auto& mpdu : mpdus)
154  {
155  queueIds.insert(WifiMacQueueContainer::GetQueueId(mpdu));
156  }
157 
158  for (const auto& queueId : queueIds)
159  {
160  if (auto item = GetWifiMacQueue(ac)->PeekByQueueId(queueId))
161  {
162  SetPriority(ac,
163  queueId,
164  {item->GetExpiryTime(), std::get<WifiContainerQueueType>(queueId)});
165  }
166  }
167 }
168 
169 void
171 {
172  NS_LOG_FUNCTION(this << +ac << mpdus.size());
173 
174  std::set<WifiContainerQueueId> queueIds;
175 
176  for (const auto& mpdu : mpdus)
177  {
178  queueIds.insert(WifiMacQueueContainer::GetQueueId(mpdu));
179  }
180 
181  for (const auto& queueId : queueIds)
182  {
183  if (auto item = GetWifiMacQueue(ac)->PeekByQueueId(queueId))
184  {
185  SetPriority(ac,
186  queueId,
187  {item->GetExpiryTime(), std::get<WifiContainerQueueType>(queueId)});
188  }
189  }
190 }
191 
192 } // namespace ns3
Hold variables of type enum.
Definition: enum.h:56
FcfsWifiQueueScheduler is a wifi queue scheduler that serves data frames in a first come first serve ...
void DoNotifyDequeue(AcIndex ac, const std::list< Ptr< WifiMpdu >> &mpdus) override
Notify the scheduler that the given list of MPDUs have been dequeued by the given Access Category.
Ptr< WifiMpdu > HasToDropBeforeEnqueuePriv(AcIndex ac, Ptr< WifiMpdu > mpdu) override
Check whether an MPDU has to be dropped before enqueuing the given MPDU.
static TypeId GetTypeId()
Get the type ID.
void DoNotifyEnqueue(AcIndex ac, Ptr< WifiMpdu > mpdu) override
Notify the scheduler that the given MPDU has been enqueued by the given Access Category.
void DoNotifyRemove(AcIndex ac, const std::list< Ptr< WifiMpdu >> &mpdus) override
Notify the scheduler that the given list of MPDUs have been removed by the given Access Category.
DropPolicy m_dropPolicy
Drop behavior of queue.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
static WifiContainerQueueId GetQueueId(Ptr< const WifiMpdu > mpdu)
Return the QueueId identifying the container queue in which the given MPDU is (or is to be) enqueued.
WifiMacQueueSchedulerImpl is a template class enabling the definition of different types of priority ...
Ptr< WifiMacQueue > GetWifiMacQueue(AcIndex ac) const
Get the wifi MAC queue associated with the given Access Category.
const SortedQueues & GetSortedQueues(AcIndex ac) const
Get a const reference to the sorted list of container queues for the given Access Category.
void SetPriority(AcIndex ac, const WifiContainerQueueId &queueId, const FcfsPrio &priority)
Set the priority for the given container queue belonging to the given Access Category.
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: enum.h:205
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_TEMPLATE_DEFINE(name)
Initialize a reference to a Log component.
Definition: log.h:236
#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 ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
AcIndex
This enumeration defines the Access Categories as an enumeration with values corresponding to the AC ...
Definition: qos-utils.h:72
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.h:157
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:163
bool operator<(const EventId &a, const EventId &b)
Definition: event-id.h:170
#define list
Definition of priority for container queues.
WifiContainerQueueType type
type of container queue
Time priority
time priority