wifi: FCFS queue scheduler prioritizes control frames
This commit is contained in:
committed by
Stefano Avallone
parent
45f726abd7
commit
4bf26a41aa
@@ -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<WifiMpdu> 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<WifiContainerQueueType>(sortedQueuesIt->second.get().first) ==
|
||||
WIFI_MGT_QUEUE)
|
||||
for (const auto& [priority, queueInfo] : GetSortedQueues(ac))
|
||||
{
|
||||
sortedQueuesIt++;
|
||||
}
|
||||
if (std::get<WifiContainerQueueType>(queueInfo.get().first) == WIFI_MGT_QUEUE ||
|
||||
std::get<WifiContainerQueueType>(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<WifiMpdu> 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<WifiMpdu> 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<WifiContainerQueueType>(queueId)});
|
||||
}
|
||||
|
||||
void
|
||||
@@ -120,15 +157,11 @@ FcfsWifiQueueScheduler::DoNotifyDequeue(AcIndex ac, const std::list<Ptr<WifiMpdu
|
||||
|
||||
for (const auto& queueId : queueIds)
|
||||
{
|
||||
if (std::get<WifiContainerQueueType>(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<WifiContainerQueueType>(queueId)});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,15 +180,11 @@ FcfsWifiQueueScheduler::DoNotifyRemove(AcIndex ac, const std::list<Ptr<WifiMpdu>
|
||||
|
||||
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<WifiContainerQueueType>(queueId)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Time>
|
||||
struct FcfsPrio
|
||||
{
|
||||
Time priority; ///< time priority
|
||||
WifiContainerQueueType type; ///< type of container queue
|
||||
};
|
||||
|
||||
/**
|
||||
* \param lhs the left hand side priority
|
||||
* \param rhs the right hand side priority
|
||||
* \return whether the left hand side priority is equal to the right hand side priority
|
||||
*/
|
||||
bool operator==(const FcfsPrio& lhs, const FcfsPrio& rhs);
|
||||
/**
|
||||
* \param lhs the left hand side priority
|
||||
* \param rhs the right hand side priority
|
||||
* \return whether the left hand side priority is less than the right hand side priority
|
||||
*/
|
||||
bool operator<(const FcfsPrio& lhs, const FcfsPrio& rhs);
|
||||
|
||||
/**
|
||||
* \ingroup wifi
|
||||
*
|
||||
* FcfsWifiQueueScheduler is a wifi queue scheduler that serves data frames in a
|
||||
* first come first serve fashion. Control frames have the highest priority.
|
||||
* Management frames have the second highest priority. Hence, data frames are
|
||||
* served after control and management frames.
|
||||
*/
|
||||
class FcfsWifiQueueScheduler : public WifiMacQueueSchedulerImpl<FcfsPrio>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user