From 00f8567e88fffb93b88673350399d330aa9da4e6 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Thu, 2 Apr 2020 08:35:16 -0700 Subject: [PATCH] [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. --- src/core/thread/mesh_forwarder.hpp | 4 +- src/core/thread/mesh_forwarder_ftd.cpp | 65 +++++++++++++++++++------- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/core/thread/mesh_forwarder.hpp b/src/core/thread/mesh_forwarder.hpp index 772613a06..961776849 100644 --- a/src/core/thread/mesh_forwarder.hpp +++ b/src/core/thread/mesh_forwarder.hpp @@ -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 diff --git a/src/core/thread/mesh_forwarder_ftd.cpp b/src/core/thread/mesh_forwarder_ftd.cpp index 60f86bb9f..f67dfc97f 100644 --- a/src/core/thread/mesh_forwarder_ftd.cpp +++ b/src/core/thread/mesh_forwarder_ftd.cpp @@ -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; }