wifi: Prevent extraction of inflight MPDUs with lifetime expired

This commit is contained in:
Stefano Avallone
2023-03-09 13:07:03 +01:00
parent 1f54892b7e
commit 101a5a1a40
2 changed files with 47 additions and 27 deletions

View File

@@ -123,53 +123,73 @@ WifiMacQueueContainer::ExtractExpiredMpdus(const WifiContainerQueueId& queueId)
std::pair<WifiMacQueueContainer::iterator, WifiMacQueueContainer::iterator>
WifiMacQueueContainer::DoExtractExpiredMpdus(ContainerQueue& queue) const
{
std::optional<std::pair<WifiMacQueueContainer::iterator, WifiMacQueueContainer::iterator>> ret;
iterator firstExpiredIt = queue.begin();
iterator lastExpiredIt = firstExpiredIt;
Time now = Simulator::Now();
while (lastExpiredIt != queue.end() && lastExpiredIt->expiryTime <= now)
do
{
lastExpiredIt->expired = true;
// this MPDU is no longer queued
lastExpiredIt->ac = AC_UNDEF;
lastExpiredIt->inflights.clear();
lastExpiredIt->deleter(lastExpiredIt->mpdu);
// advance firstExpiredIt and lastExpiredIt to skip all inflight MPDUs
for (firstExpiredIt = lastExpiredIt;
firstExpiredIt != queue.end() && !firstExpiredIt->inflights.empty();
++firstExpiredIt, ++lastExpiredIt)
{
}
WifiContainerQueueId queueId = GetQueueId(lastExpiredIt->mpdu);
auto it = m_nBytesPerQueue.find(queueId);
NS_ASSERT(it != m_nBytesPerQueue.end());
NS_ASSERT(it->second >= lastExpiredIt->mpdu->GetSize());
it->second -= lastExpiredIt->mpdu->GetSize();
if (!ret)
{
// we get here in the first iteration only
ret = std::make_pair(firstExpiredIt, lastExpiredIt);
}
++lastExpiredIt;
}
// advance lastExpiredIt as we encounter MPDUs with expired lifetime that are not inflight
while (lastExpiredIt != queue.end() && lastExpiredIt->expiryTime <= now &&
lastExpiredIt->inflights.empty())
{
lastExpiredIt->expired = true;
// this MPDU is no longer queued
lastExpiredIt->ac = AC_UNDEF;
lastExpiredIt->deleter(lastExpiredIt->mpdu);
if (lastExpiredIt != firstExpiredIt)
{
// transfer MPDUs with expired lifetime to the tail of m_expiredQueue
m_expiredQueue.splice(m_expiredQueue.end(), queue, firstExpiredIt, lastExpiredIt);
return {firstExpiredIt, m_expiredQueue.end()};
}
WifiContainerQueueId queueId = GetQueueId(lastExpiredIt->mpdu);
auto it = m_nBytesPerQueue.find(queueId);
NS_ASSERT(it != m_nBytesPerQueue.end());
NS_ASSERT(it->second >= lastExpiredIt->mpdu->GetSize());
it->second -= lastExpiredIt->mpdu->GetSize();
return {m_expiredQueue.end(), m_expiredQueue.end()};
++lastExpiredIt;
}
if (lastExpiredIt != firstExpiredIt)
{
// transfer non-inflight MPDUs with expired lifetime to the tail of m_expiredQueue
m_expiredQueue.splice(m_expiredQueue.end(), queue, firstExpiredIt, lastExpiredIt);
ret->second = m_expiredQueue.end();
}
} while (lastExpiredIt != firstExpiredIt);
return *ret;
}
std::pair<WifiMacQueueContainer::iterator, WifiMacQueueContainer::iterator>
WifiMacQueueContainer::ExtractAllExpiredMpdus() const
{
iterator firstExpiredIt = m_expiredQueue.end();
std::optional<WifiMacQueueContainer::iterator> firstExpiredIt;
for (auto& queue : m_queues)
{
auto [firstIt, lastIt] = DoExtractExpiredMpdus(queue.second);
if (firstIt != lastIt && firstExpiredIt == m_expiredQueue.end())
if (firstIt != lastIt && !firstExpiredIt)
{
// this is the first queue with MPDUs with expired lifetime
firstExpiredIt = firstIt;
}
}
return {firstExpiredIt, m_expiredQueue.end()};
return std::make_pair(firstExpiredIt ? *firstExpiredIt : m_expiredQueue.end(),
m_expiredQueue.end());
}
std::pair<WifiMacQueueContainer::iterator, WifiMacQueueContainer::iterator>

View File

@@ -170,7 +170,7 @@ class WifiMacQueueContainer
uint32_t GetNBytes(const WifiContainerQueueId& queueId) const;
/**
* Transfer MPDUs with expired lifetime in the container queue identified by
* Transfer non-inflight MPDUs with expired lifetime in the container queue identified by
* the given QueueId to the container queue storing MPDUs with expired lifetime.
*
* \param queueId the QueueId identifying the container queue
@@ -179,8 +179,8 @@ class WifiMacQueueContainer
*/
std::pair<iterator, iterator> ExtractExpiredMpdus(const WifiContainerQueueId& queueId) const;
/**
* Transfer MPDUs with expired lifetime in all the container queues to the container
* queue storing MPDUs with expired lifetime.
* Transfer non-inflight MPDUs with expired lifetime in all the container queues to the
* container queue storing MPDUs with expired lifetime.
*
* \return the range [first, last) of iterators pointing to the MPDUs transferred
* to the container queue storing MPDUs with expired lifetime
@@ -197,7 +197,7 @@ class WifiMacQueueContainer
private:
/**
* Transfer MPDUs with expired lifetime in the given container queue to the
* Transfer non-inflight MPDUs with expired lifetime in the given container queue to the
* container queue storing MPDUs with expired lifetime.
*
* \param queue the given container queue