[mesh-forwarder] include address resolving queue in message eviction (#4776)

The existing implementation only considered the forwarding queue when
looking for a message to evict. This ignores message buffers that may
be buffered in other message queues.

This commit adds the ability to evict messages in the address resolver
queue. The lowest priority message from either the forwarding or
address resolver queue is selected for eviction.
This commit is contained in:
Jonathan Hui
2020-04-02 08:35:16 -07:00
committed by GitHub
parent 5ef14ccc9c
commit 00f8567e88
2 changed files with 51 additions and 18 deletions
+2 -2
View File
@@ -310,7 +310,7 @@ public:
* @returns A reference to the resolving queue.
*
*/
const MessageQueue &GetResolvingQueue(void) const { return mResolvingQueue; }
const PriorityQueue &GetResolvingQueue(void) const { return mResolvingQueue; }
#endif
private:
@@ -519,7 +519,7 @@ private:
#if OPENTHREAD_FTD
FragmentPriorityEntry mFragmentEntries[kNumFragmentPriorityEntries];
MessageQueue mResolvingQueue;
PriorityQueue mResolvingQueue;
IndirectSender mIndirectSender;
#endif
+49 -16
View File
@@ -184,36 +184,69 @@ void MeshForwarder::HandleResolved(const Ip6::Address &aEid, otError aError)
otError MeshForwarder::EvictMessage(uint8_t aPriority)
{
otError error = OT_ERROR_NOT_FOUND;
Message *message;
otError error = OT_ERROR_NOT_FOUND;
PriorityQueue *queues[] = {&mResolvingQueue, &mSendQueue};
Message * evict = NULL;
VerifyOrExit((message = mSendQueue.GetTail()) != NULL);
// search for a lower priority message to evict (choose lowest priority message among all queues)
for (uint8_t index = 0; index < OT_ARRAY_LENGTH(queues); index++)
{
for (uint8_t priority = 0; priority < aPriority; priority++)
{
for (Message *message = queues[index]->GetHeadForPriority(priority); message; message = message->GetNext())
{
if (message->GetPriority() != priority)
{
break;
}
if (message->GetPriority() < aPriority)
if (message->GetDoNotEvict())
{
continue;
}
evict = message;
aPriority = priority;
break;
}
}
}
if (evict != NULL)
{
VerifyOrExit(!message->GetDoNotEvict());
RemoveMessage(*message);
ExitNow(error = OT_ERROR_NONE);
}
else
for (uint8_t priority = aPriority; priority < Message::kNumPriorities; priority++)
{
while (aPriority <= Message::kPriorityNet)
// search for an equal or higher priority indirect message to evict
for (Message *message = mSendQueue.GetHeadForPriority(aPriority); message; message = message->GetNext())
{
for (message = mSendQueue.GetHeadForPriority(aPriority); message && (message->GetPriority() == aPriority);
message = message->GetNext())
if (message->GetPriority() != priority)
{
if (message->IsChildPending())
{
RemoveMessage(*message);
ExitNow(error = OT_ERROR_NONE);
}
break;
}
aPriority++;
if (message->GetDoNotEvict())
{
continue;
}
if (message->IsChildPending())
{
evict = message;
ExitNow(error = OT_ERROR_NONE);
}
}
}
exit:
if (error == OT_ERROR_NONE)
{
RemoveMessage(*evict);
}
return error;
}