From 4bf26a41aa011b85e5f0044370cb87cccfc764c6 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Wed, 23 Nov 2022 12:23:04 +0100 Subject: [PATCH] wifi: FCFS queue scheduler prioritizes control frames --- src/wifi/model/fcfs-wifi-queue-scheduler.cc | 93 ++++++++++++++------- src/wifi/model/fcfs-wifi-queue-scheduler.h | 33 +++++++- 2 files changed, 90 insertions(+), 36 deletions(-) diff --git a/src/wifi/model/fcfs-wifi-queue-scheduler.cc b/src/wifi/model/fcfs-wifi-queue-scheduler.cc index a72623c88..e48e5fac4 100644 --- a/src/wifi/model/fcfs-wifi-queue-scheduler.cc +++ b/src/wifi/model/fcfs-wifi-queue-scheduler.cc @@ -29,6 +29,38 @@ namespace ns3 NS_LOG_COMPONENT_DEFINE("FcfsWifiQueueScheduler"); +bool +operator==(const FcfsPrio& lhs, const FcfsPrio& rhs) +{ + return lhs.priority == rhs.priority && lhs.type == rhs.type; +} + +bool +operator<(const FcfsPrio& lhs, const FcfsPrio& rhs) +{ + // Control queues have the highest priority + if (lhs.type == WIFI_CTL_QUEUE && rhs.type != WIFI_CTL_QUEUE) + { + return true; + } + if (lhs.type != WIFI_CTL_QUEUE && rhs.type == WIFI_CTL_QUEUE) + { + return false; + } + // Management queues have the second highest priority + if (lhs.type == WIFI_MGT_QUEUE && rhs.type != WIFI_MGT_QUEUE) + { + return true; + } + if (lhs.type != WIFI_MGT_QUEUE && rhs.type == WIFI_MGT_QUEUE) + { + return false; + } + // we get here if both priority values refer to container queues of the same type, + // hence we can compare the time values. + return lhs.priority < rhs.priority; +} + NS_OBJECT_ENSURE_REGISTERED(FcfsWifiQueueScheduler); TypeId @@ -65,23 +97,31 @@ FcfsWifiQueueScheduler::HasToDropBeforeEnqueuePriv(AcIndex ac, Ptr mpd return nullptr; } - // Management frames should be prioritized - if (m_dropPolicy == DROP_OLDEST || mpdu->GetHeader().IsMgt()) + // Control and management frames should be prioritized + if (m_dropPolicy == DROP_OLDEST || mpdu->GetHeader().IsCtl() || mpdu->GetHeader().IsMgt()) { - auto sortedQueuesIt = GetSortedQueues(ac).begin(); - - while (sortedQueuesIt != GetSortedQueues(ac).end() && - std::get(sortedQueuesIt->second.get().first) == - WIFI_MGT_QUEUE) + for (const auto& [priority, queueInfo] : GetSortedQueues(ac)) { - sortedQueuesIt++; - } + if (std::get(queueInfo.get().first) == WIFI_MGT_QUEUE || + std::get(queueInfo.get().first) == WIFI_CTL_QUEUE) + { + // do not drop control or management frames + continue; + } - if (sortedQueuesIt != GetSortedQueues(ac).end()) - { - return queue->PeekByQueueId(sortedQueuesIt->second.get().first); + // do not drop frames that are inflight or to be retransmitted + Ptr item; + while ((item = queue->PeekByQueueId(queueInfo.get().first, item))) + { + if (!item->IsInFlight() && !item->GetHeader().IsRetry()) + { + NS_LOG_DEBUG("Dropping " << *item); + return item; + } + } } } + NS_LOG_DEBUG("Dropping received MPDU: " << *mpdu); return mpdu; } @@ -100,10 +140,7 @@ FcfsWifiQueueScheduler::DoNotifyEnqueue(AcIndex ac, Ptr mpdu) return; } - auto priority = - (mpdu->GetHeader().IsMgt() ? Seconds(0) // Highest priority for management frames - : mpdu->GetExpiryTime()); - SetPriority(ac, queueId, priority); + SetPriority(ac, queueId, {mpdu->GetExpiryTime(), std::get(queueId)}); } void @@ -120,15 +157,11 @@ FcfsWifiQueueScheduler::DoNotifyDequeue(AcIndex ac, const std::list(queueId) == WIFI_MGT_QUEUE) + if (auto item = GetWifiMacQueue(ac)->PeekByQueueId(queueId)) { - // the priority of management queues does not change - continue; - } - - if (auto item = GetWifiMacQueue(ac)->PeekByQueueId(queueId); item != nullptr) - { - SetPriority(ac, queueId, item->GetExpiryTime()); + SetPriority(ac, + queueId, + {item->GetExpiryTime(), std::get(queueId)}); } } } @@ -147,15 +180,11 @@ FcfsWifiQueueScheduler::DoNotifyRemove(AcIndex ac, const std::list for (const auto& queueId : queueIds) { - if (std::get<0>(queueId) == WIFI_MGT_QUEUE) + if (auto item = GetWifiMacQueue(ac)->PeekByQueueId(queueId)) { - // the priority of management queues does not change - continue; - } - - if (auto item = GetWifiMacQueue(ac)->PeekByQueueId(queueId); item != nullptr) - { - SetPriority(ac, queueId, item->GetExpiryTime()); + SetPriority(ac, + queueId, + {item->GetExpiryTime(), std::get(queueId)}); } } } diff --git a/src/wifi/model/fcfs-wifi-queue-scheduler.h b/src/wifi/model/fcfs-wifi-queue-scheduler.h index 0edd76eb0..00a399256 100644 --- a/src/wifi/model/fcfs-wifi-queue-scheduler.h +++ b/src/wifi/model/fcfs-wifi-queue-scheduler.h @@ -32,11 +32,36 @@ class WifiMpdu; /** * \ingroup wifi * - * FcfsWifiQueueScheduler is a wifi queue scheduler that serves data frames in a - * first come first serve fashion. Management frames have higher priority than data - * frames, hence the former will be served before the latter. + * Definition of priority for container queues. */ -class FcfsWifiQueueScheduler : public WifiMacQueueSchedulerImpl