wifi: Prevent extraction of inflight MPDUs with lifetime expired
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user