wifi: Add queue scheduler functions to (un)block all queues
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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)>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user