wifi: Add queue scheduler functions to (un)block all queues

This commit is contained in:
Stefano Avallone
2024-09-04 16:21:34 +02:00
parent c516eeff4f
commit 41c64d18be
2 changed files with 156 additions and 3 deletions

View File

@@ -87,6 +87,12 @@ class WifiMacQueueSchedulerImpl : public WifiMacQueueScheduler
const Mac48Address& txAddress,
const std::set<uint8_t>& tids,
const std::set<uint8_t>& linkIds) final;
/** @copydoc ns3::WifiMacQueueScheduler::BlockAllQueues */
void BlockAllQueues(WifiQueueBlockedReason reason, const std::set<uint8_t>& linkIds) final;
/** @copydoc ns3::WifiMacQueueScheduler::UnblockAllQueues */
void UnblockAllQueues(WifiQueueBlockedReason reason, const std::set<uint8_t>& linkIds) final;
/** @copydoc ns3::WifiMacQueueScheduler::GetAllQueuesBlockedOnLink */
bool GetAllQueuesBlockedOnLink(uint8_t linkId, WifiQueueBlockedReason reason) final;
/** @copydoc ns3::WifiMacQueueScheduler::GetQueueLinkMask */
std::optional<Mask> GetQueueLinkMask(AcIndex ac,
const WifiContainerQueueId& queueId,
@@ -267,6 +273,24 @@ class WifiMacQueueSchedulerImpl : public WifiMacQueueScheduler
const std::set<uint8_t>& tids,
const std::set<uint8_t>& linkIds);
/**
* Block or unblock the given set of links for all the container queues for the given reason.
*
* @param block true to block the queues, false to unblock
* @param reason the reason for blocking the queues
* @param linkIds set of links to block (empty to block all setup links)
*/
void DoBlockAllQueues(bool block,
WifiQueueBlockedReason reason,
const std::set<uint8_t>& linkIds);
/**
* When it is requested to block all the queues, an entry is added to this map to store the
* reason and the IDs of the links to block. This information is used to block queues that
* will be created afterwards.
*/
std::map<WifiQueueBlockedReason, std::set<uint8_t>> m_blockAllInfo;
std::vector<PerAcInfo> m_perAcInfo{AC_UNDEF}; //!< vector of per-AC information
NS_LOG_TEMPLATE_DECLARE; //!< the log component
};
@@ -366,7 +390,19 @@ WifiMacQueueSchedulerImpl<Priority, Compare>::InitQueueInfo(AcIndex ac, Ptr<cons
GetMac()->GetWifiRemoteStationManager(linkId)->GetAffiliatedStaAddress(rxAddr))
{
// the mask is not modified if linkId is already in the map
queueInfoIt->second.linkIds.emplace(linkId, Mask{});
auto [it, inserted] = queueInfoIt->second.linkIds.try_emplace(linkId);
if (inserted)
{
// linkId was not in the map, set the mask if all queues are blocked
for (const auto& [reason, linkIds] : m_blockAllInfo)
{
if (linkIds.contains(linkId))
{
it->second.set(static_cast<std::size_t>(reason), true);
}
}
}
}
else
{
@@ -390,7 +426,16 @@ WifiMacQueueSchedulerImpl<Priority, Compare>::InitQueueInfo(AcIndex ac, Ptr<cons
// is preserved)
if (linkIdsMap.empty() || linkIdsMap.cbegin()->first != *linkId)
{
linkIdsMap = {{*linkId, Mask{}}};
Mask mask;
for (const auto& [reason, linkIds] : m_blockAllInfo)
{
if (linkIds.contains(*linkId))
{
mask.set(static_cast<std::size_t>(reason), true);
}
}
linkIdsMap = {{*linkId, mask}};
}
}
@@ -517,7 +562,7 @@ WifiMacQueueSchedulerImpl<Priority, Compare>::DoBlockQueues(
auto queueInfoIt = InitQueueInfo(ac, Create<WifiMpdu>(Create<Packet>(), hdr));
for (auto& [linkId, mask] : queueInfoIt->second.linkIds)
{
if (linkIds.empty() || linkIds.count(linkId) > 0)
if (linkIds.empty() || linkIds.contains(linkId))
{
mask.set(static_cast<std::size_t>(reason), block);
}
@@ -553,6 +598,84 @@ WifiMacQueueSchedulerImpl<Priority, Compare>::UnblockQueues(
DoBlockQueues(false, reason, ac, types, rxAddress, txAddress, tids, linkIds);
}
template <class Priority, class Compare>
void
WifiMacQueueSchedulerImpl<Priority, Compare>::DoBlockAllQueues(bool block,
WifiQueueBlockedReason reason,
const std::set<uint8_t>& linkIds)
{
for (auto& perAcInfo : m_perAcInfo)
{
for (auto& [queueId, queueInfo] : perAcInfo.queueInfoMap)
{
for (auto& [linkId, mask] : queueInfo.linkIds)
{
if (linkIds.empty() || linkIds.contains(linkId))
{
mask.set(static_cast<std::size_t>(reason), block);
}
}
}
}
}
template <class Priority, class Compare>
void
WifiMacQueueSchedulerImpl<Priority, Compare>::BlockAllQueues(WifiQueueBlockedReason reason,
const std::set<uint8_t>& linkIds)
{
DoBlockAllQueues(true, reason, linkIds);
if (linkIds.empty())
{
m_blockAllInfo[reason] = GetMac()->GetLinkIds(); // all links blocked
}
else
{
m_blockAllInfo[reason].merge(std::set{linkIds});
}
}
template <class Priority, class Compare>
void
WifiMacQueueSchedulerImpl<Priority, Compare>::UnblockAllQueues(WifiQueueBlockedReason reason,
const std::set<uint8_t>& linkIds)
{
DoBlockAllQueues(false, reason, linkIds);
auto infoIt = m_blockAllInfo.find(reason);
if (infoIt == m_blockAllInfo.end())
{
return; // all queues were not blocked for the given reason
}
std::erase_if(infoIt->second,
[&](uint8_t id) { return linkIds.empty() || linkIds.contains(id); });
if (infoIt->second.empty())
{
// no more links blocked for the given reason
m_blockAllInfo.erase(infoIt);
}
}
template <class Priority, class Compare>
bool
WifiMacQueueSchedulerImpl<Priority, Compare>::GetAllQueuesBlockedOnLink(
uint8_t linkId,
WifiQueueBlockedReason reason)
{
for (const auto& [r, linkIds] : m_blockAllInfo)
{
if ((reason == WifiQueueBlockedReason::REASONS_COUNT || reason == r) &&
linkIds.contains(linkId))
{
return true;
}
}
return false;
}
template <class Priority, class Compare>
std::optional<WifiMacQueueScheduler::Mask>
WifiMacQueueSchedulerImpl<Priority, Compare>::GetQueueLinkMask(AcIndex ac,

View File

@@ -175,6 +175,36 @@ class WifiMacQueueScheduler : public Object
const std::set<uint8_t>& tids = {},
const std::set<uint8_t>& linkIds = {}) = 0;
/**
* Block the given set of links for all the container queues for the given reason.
*
* @param reason the reason for blocking the queues
* @param linkIds set of links to block (empty to block all setup links)
*/
virtual void BlockAllQueues(WifiQueueBlockedReason reason,
const std::set<uint8_t>& linkIds = {}) = 0;
/**
* Unblock the given set of links for all the container queues for the given reason.
*
* @param reason the reason for unblocking the queues
* @param linkIds set of links to unblock (empty to unblock all setup links)
*/
virtual void UnblockAllQueues(WifiQueueBlockedReason reason,
const std::set<uint8_t>& linkIds = {}) = 0;
/**
* Return whether all the container queues are blocked for the given link for the given
* reason, if different than REASONS_COUNT, or for any reason, otherwise.
*
* @param linkId the ID of the given link
* @param reason the reason to check (if different than REASONS_COUNT)
* @return whether all the container queues are blocked for the given link
*/
virtual bool GetAllQueuesBlockedOnLink(
uint8_t linkId,
WifiQueueBlockedReason reason = WifiQueueBlockedReason::REASONS_COUNT) = 0;
/// Bitset identifying the reasons to block individual links for a container queue
using Mask = std::bitset<static_cast<std::size_t>(WifiQueueBlockedReason::REASONS_COUNT)>;