mirror of
https://github.com/espressif/openthread.git
synced 2026-08-11 05:07:47 +00:00
[message] remove the AllMessageQueue in MessagePool (#3893)
This commit removes the all-messages queue from `MessagePool`. This simplifies the `Message` header `MessageInfo` and allow a message to be inserted into one linked list.
This commit is contained in:
committed by
Jonathan Hui
parent
8c08fd8815
commit
7c10be51fa
+70
-166
@@ -46,7 +46,6 @@ namespace ot {
|
||||
|
||||
MessagePool::MessagePool(Instance &aInstance)
|
||||
: InstanceLocator(aInstance)
|
||||
, mAllQueue()
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT
|
||||
// Initialize Platform buffer pool management.
|
||||
@@ -120,9 +119,7 @@ Message *MessagePool::New(uint8_t aType, uint16_t aReserveHeader, const otMessag
|
||||
|
||||
void MessagePool::Free(Message *aMessage)
|
||||
{
|
||||
assert(aMessage->Next(MessageInfo::kListAll) == NULL && aMessage->Prev(MessageInfo::kListAll) == NULL);
|
||||
|
||||
assert(aMessage->Next(MessageInfo::kListInterface) == NULL && aMessage->Prev(MessageInfo::kListInterface) == NULL);
|
||||
assert(aMessage->Next() == NULL && aMessage->Prev() == NULL);
|
||||
|
||||
FreeBuffers(static_cast<Buffer *>(aMessage));
|
||||
}
|
||||
@@ -206,63 +203,6 @@ uint16_t MessagePool::GetFreeBufferCount(void) const
|
||||
return rval;
|
||||
}
|
||||
|
||||
Message *MessagePool::Iterator::Next(void) const
|
||||
{
|
||||
Message *next;
|
||||
|
||||
VerifyOrExit(mMessage != NULL, next = NULL);
|
||||
|
||||
if (mMessage == mMessage->GetMessagePool()->GetAllMessagesTail().GetMessage())
|
||||
{
|
||||
next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
next = mMessage->Next(MessageInfo::kListAll);
|
||||
}
|
||||
|
||||
exit:
|
||||
return next;
|
||||
}
|
||||
|
||||
Message *MessagePool::Iterator::Prev(void) const
|
||||
{
|
||||
Message *prev;
|
||||
|
||||
VerifyOrExit(mMessage != NULL, prev = NULL);
|
||||
|
||||
if (mMessage == mMessage->GetMessagePool()->GetAllMessagesHead().GetMessage())
|
||||
{
|
||||
prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = mMessage->Prev(MessageInfo::kListAll);
|
||||
}
|
||||
|
||||
exit:
|
||||
return prev;
|
||||
}
|
||||
|
||||
MessagePool::Iterator MessagePool::GetAllMessagesHead(void) const
|
||||
{
|
||||
Message *head;
|
||||
Message *tail;
|
||||
|
||||
tail = GetAllMessagesTail().GetMessage();
|
||||
|
||||
if (tail != NULL)
|
||||
{
|
||||
head = tail->Next(MessageInfo::kListAll);
|
||||
}
|
||||
else
|
||||
{
|
||||
head = NULL;
|
||||
}
|
||||
|
||||
return Iterator(head);
|
||||
}
|
||||
|
||||
otError Message::ResizeMessage(uint16_t aLength)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
@@ -318,7 +258,7 @@ Message *Message::GetNext(void) const
|
||||
tail = messageQueue->GetTail();
|
||||
}
|
||||
|
||||
next = (this == tail) ? NULL : Next(MessageInfo::kListInterface);
|
||||
next = (this == tail) ? NULL : Next();
|
||||
|
||||
exit:
|
||||
return next;
|
||||
@@ -430,10 +370,6 @@ otError Message::SetPriority(uint8_t aPriority)
|
||||
priorityQueue = mBuffer.mHead.mInfo.mQueue.mPriority;
|
||||
priorityQueue->Dequeue(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetMessagePool()->GetAllMessagesQueue()->RemoveFromList(MessageInfo::kListAll, *this);
|
||||
}
|
||||
|
||||
mBuffer.mHead.mInfo.mPriority = aPriority;
|
||||
|
||||
@@ -441,10 +377,6 @@ otError Message::SetPriority(uint8_t aPriority)
|
||||
{
|
||||
priorityQueue->Enqueue(*this);
|
||||
}
|
||||
else
|
||||
{
|
||||
GetMessagePool()->GetAllMessagesQueue()->AddToList(MessageInfo::kListAll, *this);
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -863,58 +795,9 @@ MessageQueue::MessageQueue(void)
|
||||
SetTail(NULL);
|
||||
}
|
||||
|
||||
void MessageQueue::AddToList(uint8_t aListId, Message &aMessage, QueuePosition aPosition)
|
||||
{
|
||||
assert((aMessage.Next(aListId) == NULL) && (aMessage.Prev(aListId) == NULL));
|
||||
|
||||
if (GetTail() == NULL)
|
||||
{
|
||||
aMessage.Next(aListId) = &aMessage;
|
||||
aMessage.Prev(aListId) = &aMessage;
|
||||
|
||||
SetTail(&aMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
Message *head = GetTail()->Next(aListId);
|
||||
|
||||
aMessage.Next(aListId) = head;
|
||||
aMessage.Prev(aListId) = GetTail();
|
||||
|
||||
head->Prev(aListId) = &aMessage;
|
||||
GetTail()->Next(aListId) = &aMessage;
|
||||
|
||||
if (aPosition == kQueuePositionTail)
|
||||
{
|
||||
SetTail(&aMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MessageQueue::RemoveFromList(uint8_t aListId, Message &aMessage)
|
||||
{
|
||||
assert((aMessage.Next(aListId) != NULL) && (aMessage.Prev(aListId) != NULL));
|
||||
|
||||
if (&aMessage == GetTail())
|
||||
{
|
||||
SetTail(GetTail()->Prev(aListId));
|
||||
|
||||
if (&aMessage == GetTail())
|
||||
{
|
||||
SetTail(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
aMessage.Prev(aListId)->Next(aListId) = aMessage.Next(aListId);
|
||||
aMessage.Next(aListId)->Prev(aListId) = aMessage.Prev(aListId);
|
||||
|
||||
aMessage.Prev(aListId) = NULL;
|
||||
aMessage.Next(aListId) = NULL;
|
||||
}
|
||||
|
||||
Message *MessageQueue::GetHead(void) const
|
||||
{
|
||||
return (GetTail() == NULL) ? NULL : GetTail()->Next(MessageInfo::kListInterface);
|
||||
return (GetTail() == NULL) ? NULL : GetTail()->Next();
|
||||
}
|
||||
|
||||
otError MessageQueue::Enqueue(Message &aMessage, QueuePosition aPosition)
|
||||
@@ -925,10 +808,30 @@ otError MessageQueue::Enqueue(Message &aMessage, QueuePosition aPosition)
|
||||
|
||||
aMessage.SetMessageQueue(this);
|
||||
|
||||
AddToList(MessageInfo::kListInterface, aMessage, aPosition);
|
||||
assert((aMessage.Next() == NULL) && (aMessage.Prev() == NULL));
|
||||
|
||||
// Any new message is always added to the end of the `AllMessageQueue` list.
|
||||
aMessage.GetMessagePool()->GetAllMessagesQueue()->AddToList(MessageInfo::kListAll, aMessage);
|
||||
if (GetTail() == NULL)
|
||||
{
|
||||
aMessage.Next() = &aMessage;
|
||||
aMessage.Prev() = &aMessage;
|
||||
|
||||
SetTail(&aMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
Message *head = GetTail()->Next();
|
||||
|
||||
aMessage.Next() = head;
|
||||
aMessage.Prev() = GetTail();
|
||||
|
||||
head->Prev() = &aMessage;
|
||||
GetTail()->Next() = &aMessage;
|
||||
|
||||
if (aPosition == kQueuePositionTail)
|
||||
{
|
||||
SetTail(&aMessage);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -940,8 +843,23 @@ otError MessageQueue::Dequeue(Message &aMessage)
|
||||
|
||||
VerifyOrExit(aMessage.GetMessageQueue() == this, error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
RemoveFromList(MessageInfo::kListInterface, aMessage);
|
||||
aMessage.GetMessagePool()->GetAllMessagesQueue()->RemoveFromList(MessageInfo::kListAll, aMessage);
|
||||
assert((aMessage.Next() != NULL) && (aMessage.Prev() != NULL));
|
||||
|
||||
if (&aMessage == GetTail())
|
||||
{
|
||||
SetTail(GetTail()->Prev());
|
||||
|
||||
if (&aMessage == GetTail())
|
||||
{
|
||||
SetTail(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
aMessage.Prev()->Next() = aMessage.Next();
|
||||
aMessage.Next()->Prev() = aMessage.Prev();
|
||||
|
||||
aMessage.Prev() = NULL;
|
||||
aMessage.Next() = NULL;
|
||||
|
||||
aMessage.SetMessageQueue(NULL);
|
||||
|
||||
@@ -996,7 +914,7 @@ Message *PriorityQueue::GetHead(void) const
|
||||
|
||||
tail = FindFirstNonNullTail(0);
|
||||
|
||||
return (tail == NULL) ? NULL : tail->Next(MessageInfo::kListInterface);
|
||||
return (tail == NULL) ? NULL : tail->Next();
|
||||
}
|
||||
|
||||
Message *PriorityQueue::GetHeadForPriority(uint8_t aPriority) const
|
||||
@@ -1010,7 +928,7 @@ Message *PriorityQueue::GetHeadForPriority(uint8_t aPriority) const
|
||||
|
||||
assert(previousTail != NULL);
|
||||
|
||||
head = previousTail->Next(MessageInfo::kListInterface);
|
||||
head = previousTail->Next();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1025,46 +943,57 @@ Message *PriorityQueue::GetTail(void) const
|
||||
return FindFirstNonNullTail(0);
|
||||
}
|
||||
|
||||
void PriorityQueue::AddToList(uint8_t aListId, Message &aMessage)
|
||||
otError PriorityQueue::Enqueue(Message &aMessage)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t priority;
|
||||
Message *tail;
|
||||
Message *next;
|
||||
|
||||
VerifyOrExit(!aMessage.IsInAQueue(), error = OT_ERROR_ALREADY);
|
||||
|
||||
aMessage.SetPriorityQueue(this);
|
||||
|
||||
priority = aMessage.GetPriority();
|
||||
|
||||
tail = FindFirstNonNullTail(priority);
|
||||
|
||||
if (tail != NULL)
|
||||
{
|
||||
next = tail->Next(aListId);
|
||||
next = tail->Next();
|
||||
|
||||
aMessage.Next(aListId) = next;
|
||||
aMessage.Prev(aListId) = tail;
|
||||
next->Prev(aListId) = &aMessage;
|
||||
tail->Next(aListId) = &aMessage;
|
||||
aMessage.Next() = next;
|
||||
aMessage.Prev() = tail;
|
||||
next->Prev() = &aMessage;
|
||||
tail->Next() = &aMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
aMessage.Next(aListId) = &aMessage;
|
||||
aMessage.Prev(aListId) = &aMessage;
|
||||
aMessage.Next() = &aMessage;
|
||||
aMessage.Prev() = &aMessage;
|
||||
}
|
||||
|
||||
mTails[priority] = &aMessage;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
void PriorityQueue::RemoveFromList(uint8_t aListId, Message &aMessage)
|
||||
otError PriorityQueue::Dequeue(Message &aMessage)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
uint8_t priority;
|
||||
Message *tail;
|
||||
|
||||
VerifyOrExit(aMessage.GetPriorityQueue() == this, error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
priority = aMessage.GetPriority();
|
||||
|
||||
tail = mTails[priority];
|
||||
|
||||
if (&aMessage == tail)
|
||||
{
|
||||
tail = tail->Prev(aListId);
|
||||
tail = tail->Prev();
|
||||
|
||||
if ((&aMessage == tail) || (tail->GetPriority() != priority))
|
||||
{
|
||||
@@ -1074,35 +1003,10 @@ void PriorityQueue::RemoveFromList(uint8_t aListId, Message &aMessage)
|
||||
mTails[priority] = tail;
|
||||
}
|
||||
|
||||
aMessage.Next(aListId)->Prev(aListId) = aMessage.Prev(aListId);
|
||||
aMessage.Prev(aListId)->Next(aListId) = aMessage.Next(aListId);
|
||||
aMessage.Next(aListId) = NULL;
|
||||
aMessage.Prev(aListId) = NULL;
|
||||
}
|
||||
|
||||
otError PriorityQueue::Enqueue(Message &aMessage)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(!aMessage.IsInAQueue(), error = OT_ERROR_ALREADY);
|
||||
|
||||
aMessage.SetPriorityQueue(this);
|
||||
|
||||
AddToList(MessageInfo::kListInterface, aMessage);
|
||||
aMessage.GetMessagePool()->GetAllMessagesQueue()->AddToList(MessageInfo::kListAll, aMessage);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
otError PriorityQueue::Dequeue(Message &aMessage)
|
||||
{
|
||||
otError error = OT_ERROR_NONE;
|
||||
|
||||
VerifyOrExit(aMessage.GetPriorityQueue() == this, error = OT_ERROR_NOT_FOUND);
|
||||
|
||||
RemoveFromList(MessageInfo::kListInterface, aMessage);
|
||||
aMessage.GetMessagePool()->GetAllMessagesQueue()->RemoveFromList(MessageInfo::kListAll, aMessage);
|
||||
aMessage.Next()->Prev() = aMessage.Prev();
|
||||
aMessage.Prev()->Next() = aMessage.Next();
|
||||
aMessage.Next() = NULL;
|
||||
aMessage.Prev() = NULL;
|
||||
|
||||
aMessage.SetMessageQueue(NULL);
|
||||
|
||||
|
||||
+17
-186
@@ -77,16 +77,9 @@ class PriorityQueue;
|
||||
*/
|
||||
struct MessageInfo
|
||||
{
|
||||
enum
|
||||
{
|
||||
kListAll = 0, ///< Identifies the all messages list (maintained by the MessagePool).
|
||||
kListInterface = 1, ///< Identifies the list for per-interface message queue.
|
||||
kNumLists = 2, ///< Number of lists.
|
||||
};
|
||||
|
||||
Message * mNext[kNumLists]; ///< A pointer to the next Message in a doubly linked list.
|
||||
Message * mPrev[kNumLists]; ///< A pointer to the previous Message in a doubly linked list.
|
||||
MessagePool *mMessagePool; ///< Identifies the message pool for this message.
|
||||
Message * mNext; ///< A pointer to the next Message in a doubly linked list.
|
||||
Message * mPrev; ///< A pointer to the previous Message in a doubly linked list.
|
||||
MessagePool *mMessagePool; ///< Identifies the message pool for this message.
|
||||
union
|
||||
{
|
||||
MessageQueue * mMessage; ///< Identifies the message queue (if any) where this message is queued.
|
||||
@@ -248,9 +241,9 @@ public:
|
||||
void Free(void);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the next message in the same interface list.
|
||||
* This method returns a pointer to the next message.
|
||||
*
|
||||
* @returns A pointer to the next message in the same interface list or NULL if at the end of the list.
|
||||
* @returns A pointer to the next message in the list or NULL if at the end of the list.
|
||||
*
|
||||
*/
|
||||
Message *GetNext(void) const;
|
||||
@@ -865,34 +858,29 @@ private:
|
||||
void SetPriorityQueue(PriorityQueue *aPriorityQueue);
|
||||
|
||||
/**
|
||||
* This method returns a reference to the `mNext` pointer for a given list.
|
||||
* This method returns a reference to the `mNext` pointer.
|
||||
*
|
||||
* @param[in] aList The index to the message list.
|
||||
*
|
||||
* @returns A reference to the mNext pointer for the specified list.
|
||||
* @returns A reference to the mNext pointer.
|
||||
*
|
||||
*/
|
||||
Message *&Next(uint8_t aList) { return mBuffer.mHead.mInfo.mNext[aList]; }
|
||||
Message *&Next(void) { return mBuffer.mHead.mInfo.mNext; }
|
||||
|
||||
/**
|
||||
* This method returns a const reference to the `mNext` pointer for a given list.
|
||||
* This method returns a reference to the `mNext` pointer (const pointer).
|
||||
*
|
||||
* @param[in] aList The index to the message list.
|
||||
*
|
||||
* @returns A const reference to the mNext pointer for the specified list.
|
||||
* @returns A reference to the mNext pointer.
|
||||
*
|
||||
*/
|
||||
Message *const &Next(uint8_t aList) const { return mBuffer.mHead.mInfo.mNext[aList]; }
|
||||
Message *const &Next(void) const { return mBuffer.mHead.mInfo.mNext; }
|
||||
|
||||
/**
|
||||
* This method returns a reference to the `mPrev` pointer for a given list.
|
||||
* This method returns a reference to the `mPrev` pointer.
|
||||
*
|
||||
* @param[in] aList The index to the message list.
|
||||
*
|
||||
* @returns A reference to the mPrev pointer for the specified list.
|
||||
* @returns A reference to the mPrev pointer.
|
||||
*
|
||||
*/
|
||||
Message *&Prev(uint8_t aList) { return mBuffer.mHead.mInfo.mPrev[aList]; }
|
||||
Message *&Prev(void) { return mBuffer.mHead.mInfo.mPrev; }
|
||||
|
||||
/**
|
||||
* This method returns the number of reserved header bytes.
|
||||
@@ -1016,34 +1004,6 @@ private:
|
||||
*
|
||||
*/
|
||||
void SetTail(Message *aMessage) { mData = aMessage; }
|
||||
|
||||
/**
|
||||
* This method adds a message to the end of the list.
|
||||
*
|
||||
* @param[in] aListId The list to add @p aMessage to.
|
||||
* @param[in] aMessage The message to add to @p aListId.
|
||||
*
|
||||
*/
|
||||
void AddToList(uint8_t aListId, Message &aMessage) { AddToList(aListId, aMessage, kQueuePositionTail); }
|
||||
|
||||
/**
|
||||
* This method adds a message at a give position (head or tail) of the list.
|
||||
*
|
||||
* @param[in] aListId The list to add @p aMessage to.
|
||||
* @param[in] aMessage The message to add to @p aListId.
|
||||
* @param[in] aPosition The position where to add the message.
|
||||
*
|
||||
*/
|
||||
void AddToList(uint8_t aListId, Message &aMessage, QueuePosition aPosition);
|
||||
|
||||
/**
|
||||
* This method removes a message from a list.
|
||||
*
|
||||
* @param[in] aListId The list to add @p aMessage to.
|
||||
* @param[in] aMessage The message to add to @p aListId.
|
||||
*
|
||||
*/
|
||||
void RemoveFromList(uint8_t aListId, Message &aMessage);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1122,24 +1082,6 @@ public:
|
||||
Message *GetTail(void) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* This method adds a message to a list.
|
||||
*
|
||||
* @param[in] aListId The list to add @p aMessage to.
|
||||
* @param[in] aMessage The message to add to @p aListId.
|
||||
*
|
||||
*/
|
||||
void AddToList(uint8_t aListId, Message &aMessage);
|
||||
|
||||
/**
|
||||
* This method removes a message from a list.
|
||||
*
|
||||
* @param[in] aListId The list to add @p aMessage to.
|
||||
* @param[in] aMessage The message to add to @p aListId.
|
||||
*
|
||||
*/
|
||||
void RemoveFromList(uint8_t aListId, Message &aMessage);
|
||||
|
||||
/**
|
||||
* This method increases (moves forward) the given priority while ensuring to wrap from
|
||||
* priority value `kNumPriorities` -1 back to 0.
|
||||
@@ -1179,96 +1121,6 @@ class MessagePool : public InstanceLocator
|
||||
friend class PriorityQueue;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This class represents an iterator for iterating through all queued message from this pool.
|
||||
*
|
||||
*/
|
||||
class Iterator
|
||||
{
|
||||
friend class MessagePool;
|
||||
|
||||
public:
|
||||
/**
|
||||
* This constructor initializes an empty iterator.
|
||||
*/
|
||||
Iterator(void)
|
||||
: mMessage(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the associated message with the iterator.
|
||||
*
|
||||
* @returns A pointer to associated message with this iterator.
|
||||
*
|
||||
*/
|
||||
Message *GetMessage(void) const { return mMessage; }
|
||||
|
||||
/**
|
||||
* This method returns `true` if the iterator is empty (i.e., associated with a NULL message)
|
||||
*
|
||||
* @returns `true` if the iterator is empty, `false` otherwise.
|
||||
*/
|
||||
bool IsEmpty(void) const { return (mMessage == NULL); }
|
||||
|
||||
/**
|
||||
* This method returns `true` if the iterator has ended (beyond the last message on list).
|
||||
*
|
||||
* @returns `true` if the iterator has ended , `false` otherwise.
|
||||
*/
|
||||
bool HasEnded(void) const { return IsEmpty(); }
|
||||
|
||||
/**
|
||||
* This method returns a new iterator corresponding to next message on the list.
|
||||
*
|
||||
* @returns An iterator corresponding to next message on the list.
|
||||
*
|
||||
*/
|
||||
Iterator GetNext(void) const { return Iterator(Next()); }
|
||||
|
||||
/**
|
||||
* This method returns a new iterator corresponding to previous message on the list.
|
||||
*
|
||||
* @returns An iterator corresponding to previous message on the list.
|
||||
*
|
||||
*/
|
||||
Iterator GetPrev(void) const { return Iterator(Prev()); }
|
||||
|
||||
/**
|
||||
* This method moves the current iterator to the next message on the list.
|
||||
*
|
||||
* @returns A reference to current iterator.
|
||||
*
|
||||
*/
|
||||
Iterator &GoToNext(void)
|
||||
{
|
||||
mMessage = Next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method moves the current iterator to the previous message on the list.
|
||||
*
|
||||
* @returns A reference to current iterator.
|
||||
*
|
||||
*/
|
||||
Iterator &GoToPrev(void)
|
||||
{
|
||||
mMessage = Prev();
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
explicit Iterator(Message *aMessage)
|
||||
: mMessage(aMessage)
|
||||
{
|
||||
}
|
||||
Message *Next(void) const;
|
||||
Message *Prev(void) const;
|
||||
|
||||
Message *mMessage;
|
||||
};
|
||||
|
||||
/**
|
||||
* This constructor initializes the object.
|
||||
*
|
||||
@@ -1311,24 +1163,6 @@ public:
|
||||
*/
|
||||
void Free(Message *aMessage);
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the first message (head) in the all-messages list.
|
||||
* Messages are sorted based on their priority (head with highest priority) and order by which they are enqueued.
|
||||
*
|
||||
* @returns A pointer to the first message.
|
||||
*
|
||||
*/
|
||||
Iterator GetAllMessagesHead(void) const;
|
||||
|
||||
/**
|
||||
* This method returns a pointer to the last message (head) in the all-messages list.
|
||||
* Messages are sorted based on their priority (head with highest priority) and order by which they are enqueued.
|
||||
*
|
||||
* @returns A pointer to the last message.
|
||||
*
|
||||
*/
|
||||
Iterator GetAllMessagesTail(void) const { return Iterator(mAllQueue.GetTail()); }
|
||||
|
||||
/**
|
||||
* This method returns the number of free buffers.
|
||||
*
|
||||
@@ -1343,18 +1177,15 @@ private:
|
||||
kDefaultMessagePriority = Message::kPriorityNormal,
|
||||
};
|
||||
|
||||
Buffer * NewBuffer(uint8_t aPriority);
|
||||
void FreeBuffers(Buffer *aBuffer);
|
||||
otError ReclaimBuffers(int aNumBuffers, uint8_t aPriority);
|
||||
PriorityQueue *GetAllMessagesQueue(void) { return &mAllQueue; }
|
||||
Buffer *NewBuffer(uint8_t aPriority);
|
||||
void FreeBuffers(Buffer *aBuffer);
|
||||
otError ReclaimBuffers(int aNumBuffers, uint8_t aPriority);
|
||||
|
||||
#if OPENTHREAD_CONFIG_PLATFORM_MESSAGE_MANAGEMENT == 0
|
||||
uint16_t mNumFreeBuffers;
|
||||
Buffer mBuffers[kNumBuffers];
|
||||
Buffer * mFreeBuffers;
|
||||
#endif
|
||||
|
||||
PriorityQueue mAllQueue;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -112,67 +112,6 @@ void VerifyPriorityQueueContent(ot::PriorityQueue &aPriorityQueue, int aExpected
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// This function verifies the content of the all message queue to match the passed in messages
|
||||
void VerifyAllMessagesContent(ot::MessagePool *aMessagePool, int aExpectedLength, ...)
|
||||
{
|
||||
va_list args;
|
||||
ot::MessagePool::Iterator it;
|
||||
ot::Message * msgArg;
|
||||
|
||||
va_start(args, aExpectedLength);
|
||||
|
||||
if (aExpectedLength == 0)
|
||||
{
|
||||
VerifyOrQuit(aMessagePool->GetAllMessagesHead().IsEmpty(), "Head is not empty when expected len is zero.\n");
|
||||
VerifyOrQuit(aMessagePool->GetAllMessagesTail().IsEmpty(), "Tail is not empty when expected len is zero.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (it = aMessagePool->GetAllMessagesHead(); !it.HasEnded(); it.GoToNext())
|
||||
{
|
||||
VerifyOrQuit(aExpectedLength != 0, "AllMessagesQueue contains more entries than expected.\n");
|
||||
msgArg = va_arg(args, ot::Message *);
|
||||
VerifyOrQuit(msgArg == it.GetMessage(), "AllMessagesQueue content does not match what is expected.\n");
|
||||
aExpectedLength--;
|
||||
}
|
||||
|
||||
VerifyOrQuit(aExpectedLength == 0, "AllMessagesQueue contains less entries than expected.\n");
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// This function verifies the content of the all message queue to match the passed in messages. It goes
|
||||
// through the AllMessages list in reverse.
|
||||
void VerifyAllMessagesContentInReverse(ot::MessagePool *aMessagePool, int aExpectedLength, ...)
|
||||
{
|
||||
va_list args;
|
||||
ot::MessagePool::Iterator it;
|
||||
ot::Message * msgArg;
|
||||
|
||||
va_start(args, aExpectedLength);
|
||||
|
||||
if (aExpectedLength == 0)
|
||||
{
|
||||
VerifyOrQuit(aMessagePool->GetAllMessagesHead().IsEmpty(), "Head is not empty when expected len is zero.\n");
|
||||
VerifyOrQuit(aMessagePool->GetAllMessagesTail().IsEmpty(), "Tail is not empty when expected len is zero.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (it = aMessagePool->GetAllMessagesTail(); !it.HasEnded(); it.GoToPrev())
|
||||
{
|
||||
VerifyOrQuit(aExpectedLength != 0, "AllMessagesQueue contains more entries than expected.\n");
|
||||
msgArg = va_arg(args, ot::Message *);
|
||||
VerifyOrQuit(msgArg == it.GetMessage(), "AllMessagesQueue content does not match what is expected.\n");
|
||||
aExpectedLength--;
|
||||
}
|
||||
|
||||
VerifyOrQuit(aExpectedLength == 0, "AllMessagesQueue contains less entries than expected.\n");
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// This function verifies the content of the message queue to match the passed in messages
|
||||
void VerifyMsgQueueContent(ot::MessageQueue &aMessageQueue, int aExpectedLength, ...)
|
||||
{
|
||||
@@ -207,15 +146,14 @@ void VerifyMsgQueueContent(ot::MessageQueue &aMessageQueue, int aExpectedLength,
|
||||
|
||||
void TestPriorityQueue(void)
|
||||
{
|
||||
ot::Instance * instance;
|
||||
ot::MessagePool * messagePool;
|
||||
ot::PriorityQueue queue;
|
||||
ot::MessageQueue messageQueue;
|
||||
ot::Message * msgNet[kNumTestMessages];
|
||||
ot::Message * msgHigh[kNumTestMessages];
|
||||
ot::Message * msgNor[kNumTestMessages];
|
||||
ot::Message * msgLow[kNumTestMessages];
|
||||
ot::MessagePool::Iterator it;
|
||||
ot::Instance * instance;
|
||||
ot::MessagePool * messagePool;
|
||||
ot::PriorityQueue queue;
|
||||
ot::MessageQueue messageQueue;
|
||||
ot::Message * msgNet[kNumTestMessages];
|
||||
ot::Message * msgHigh[kNumTestMessages];
|
||||
ot::Message * msgNor[kNumTestMessages];
|
||||
ot::Message * msgLow[kNumTestMessages];
|
||||
|
||||
instance = testInitInstance();
|
||||
VerifyOrQuit(instance != NULL, "Null OpenThread instance\n");
|
||||
@@ -292,35 +230,6 @@ void TestPriorityQueue(void)
|
||||
VerifyPriorityQueueContent(queue, 8, msgNet[0], msgNet[1], msgHigh[0], msgHigh[1], msgHigh[2], msgHigh[3],
|
||||
msgNor[0], msgLow[0]);
|
||||
|
||||
// Check the MessagePool::Iterator methods.
|
||||
VerifyOrQuit(it.IsEmpty(), "Iterator::IsEmpty() failed to return `true` for an empty iterator.\n");
|
||||
VerifyOrQuit(it.GetNext().IsEmpty(), "Iterator::IsEmpty() failed to return `true` for an empty iterator.\n");
|
||||
VerifyOrQuit(it.GetPrev().IsEmpty(), "Iterator::IsEmpty() failed to return `true` for an empty iterator.\n");
|
||||
it.GoToNext();
|
||||
VerifyOrQuit(it.IsEmpty(), "Iterator::IsEmpty() failed to return `true` for an empty iterator.\n");
|
||||
it.GoToNext();
|
||||
VerifyOrQuit(it.IsEmpty(), "Iterator::IsEmpty() failed to return `true` for an empty iterator.\n");
|
||||
|
||||
it = messagePool->GetAllMessagesHead();
|
||||
VerifyOrQuit(!it.IsEmpty(), "Iterator::IsEmpty() failed to return `false` when it is not empty.\n");
|
||||
VerifyOrQuit(it.GetMessage() == msgNet[0], "Iterator::GetMessage() failed.\n");
|
||||
it = it.GetNext();
|
||||
VerifyOrQuit(!it.IsEmpty(), "Iterator::IsEmpty() failed to return `false` when it is not empty.\n");
|
||||
VerifyOrQuit(it.GetMessage() == msgNet[1], "Iterator::GetNext() failed.\n");
|
||||
it = it.GetPrev();
|
||||
VerifyOrQuit(it.GetMessage() == msgNet[0], "Iterator::GetPrev() failed.\n");
|
||||
it = it.GetPrev();
|
||||
VerifyOrQuit(it.HasEnded(), "Iterator::GetPrev() failed to return empty at head.\n");
|
||||
it = messagePool->GetAllMessagesTail();
|
||||
it = it.GetNext();
|
||||
VerifyOrQuit(it.HasEnded(), "Iterator::GetNext() failed to return empty at tail.\n");
|
||||
|
||||
// Check the AllMessage queue contents (should match the content of priority queue).
|
||||
VerifyAllMessagesContent(messagePool, 8, msgNet[0], msgNet[1], msgHigh[0], msgHigh[1], msgHigh[2], msgHigh[3],
|
||||
msgNor[0], msgLow[0]);
|
||||
VerifyAllMessagesContentInReverse(messagePool, 8, msgLow[0], msgNor[0], msgHigh[3], msgHigh[2], msgHigh[1],
|
||||
msgHigh[0], msgNet[1], msgNet[0]);
|
||||
|
||||
// Remove messages in different order and check the content of queue in each step.
|
||||
SuccessOrQuit(queue.Dequeue(*msgNet[0]), "PriorityQueue::Dequeue() failed.\n");
|
||||
VerifyPriorityQueueContent(queue, 7, msgNet[1], msgHigh[0], msgHigh[1], msgHigh[2], msgHigh[3], msgNor[0],
|
||||
@@ -339,7 +248,6 @@ void TestPriorityQueue(void)
|
||||
VerifyPriorityQueueContent(queue, 1, msgHigh[3]);
|
||||
SuccessOrQuit(queue.Dequeue(*msgHigh[3]), "PriorityQueue::Dequeue() failed.\n");
|
||||
VerifyPriorityQueueContent(queue, 0);
|
||||
VerifyAllMessagesContent(messagePool, 0);
|
||||
|
||||
// Check the failure cases: Enqueuing an already queued message, or dequeuing a message not queued.
|
||||
SuccessOrQuit(queue.Enqueue(*msgNet[0]), "PriorityQueue::Enqueue() failed.\n");
|
||||
@@ -358,7 +266,6 @@ void TestPriorityQueue(void)
|
||||
VerifyPriorityQueueContent(queue, 2, msgHigh[0], msgNor[0]);
|
||||
SuccessOrQuit(queue.Enqueue(*msgLow[0]), "PriorityQueue::Enqueue() failed.\n");
|
||||
VerifyPriorityQueueContent(queue, 3, msgHigh[0], msgNor[0], msgLow[0]);
|
||||
VerifyAllMessagesContent(messagePool, 3, msgHigh[0], msgNor[0], msgLow[0]);
|
||||
|
||||
SuccessOrQuit(msgNor[0]->SetPriority(ot::Message::kPriorityNet),
|
||||
"SetPriority failed for an already queued message.\n");
|
||||
@@ -372,7 +279,6 @@ void TestPriorityQueue(void)
|
||||
SuccessOrQuit(msgLow[0]->SetPriority(ot::Message::kPriorityHigh),
|
||||
"SetPriority failed for an already queued message.\n");
|
||||
VerifyPriorityQueueContent(queue, 3, msgNor[0], msgHigh[0], msgLow[0]);
|
||||
VerifyAllMessagesContent(messagePool, 3, msgNor[0], msgHigh[0], msgLow[0]);
|
||||
SuccessOrQuit(msgLow[0]->SetPriority(ot::Message::kPriorityNet),
|
||||
"SetPriority failed for an already queued message.\n");
|
||||
VerifyPriorityQueueContent(queue, 3, msgNor[0], msgLow[0], msgHigh[0]);
|
||||
@@ -381,51 +287,36 @@ void TestPriorityQueue(void)
|
||||
SuccessOrQuit(msgLow[0]->SetPriority(ot::Message::kPriorityLow),
|
||||
"SetPriority failed for an already queued message.\n");
|
||||
VerifyPriorityQueueContent(queue, 3, msgHigh[0], msgNor[0], msgLow[0]);
|
||||
VerifyAllMessagesContent(messagePool, 3, msgHigh[0], msgNor[0], msgLow[0]);
|
||||
VerifyAllMessagesContentInReverse(messagePool, 3, msgLow[0], msgNor[0], msgHigh[0]);
|
||||
|
||||
// Checking the AllMessages queue when adding messages from same pool to another queue.
|
||||
SuccessOrQuit(messageQueue.Enqueue(*msgNor[1]), "MessageQueue::Enqueue() failed.\n");
|
||||
VerifyAllMessagesContent(messagePool, 4, msgHigh[0], msgNor[0], msgNor[1], msgLow[0]);
|
||||
SuccessOrQuit(messageQueue.Enqueue(*msgHigh[1]), "MessageQueue::Enqueue() failed.\n");
|
||||
VerifyAllMessagesContent(messagePool, 5, msgHigh[0], msgHigh[1], msgNor[0], msgNor[1], msgLow[0]);
|
||||
VerifyAllMessagesContentInReverse(messagePool, 5, msgLow[0], msgNor[1], msgNor[0], msgHigh[1], msgHigh[0]);
|
||||
SuccessOrQuit(messageQueue.Enqueue(*msgNet[1]), "MessageQueue::Enqueue() failed.\n");
|
||||
VerifyAllMessagesContent(messagePool, 6, msgNet[1], msgHigh[0], msgHigh[1], msgNor[0], msgNor[1], msgLow[0]);
|
||||
VerifyMsgQueueContent(messageQueue, 3, msgNor[1], msgHigh[1], msgNet[1]);
|
||||
|
||||
// Change priority of message and check that order changes in the AllMessage queue and not in messageQueue.
|
||||
// Change priority of message and check for not in messageQueue.
|
||||
SuccessOrQuit(msgNor[1]->SetPriority(ot::Message::kPriorityNet),
|
||||
"SetPriority failed for an already queued message.\n");
|
||||
VerifyAllMessagesContent(messagePool, 6, msgNet[1], msgNor[1], msgHigh[0], msgHigh[1], msgNor[0], msgLow[0]);
|
||||
VerifyAllMessagesContentInReverse(messagePool, 6, msgLow[0], msgNor[0], msgHigh[1], msgHigh[0], msgNor[1],
|
||||
msgNet[1]);
|
||||
VerifyMsgQueueContent(messageQueue, 3, msgNor[1], msgHigh[1], msgNet[1]);
|
||||
|
||||
SuccessOrQuit(msgLow[0]->SetPriority(ot::Message::kPriorityHigh),
|
||||
"SetPriority failed for an already queued message.\n");
|
||||
VerifyAllMessagesContent(messagePool, 6, msgNet[1], msgNor[1], msgHigh[0], msgHigh[1], msgLow[0], msgNor[0]);
|
||||
VerifyPriorityQueueContent(queue, 3, msgHigh[0], msgLow[0], msgNor[0]);
|
||||
VerifyMsgQueueContent(messageQueue, 3, msgNor[1], msgHigh[1], msgNet[1]);
|
||||
|
||||
// Remove messages from the two queues and verify that AllMessage queue is updated correctly.
|
||||
// Remove messages from the two queues
|
||||
SuccessOrQuit(queue.Dequeue(*msgHigh[0]), "PriorityQueue::Dequeue() failed.\n");
|
||||
VerifyAllMessagesContent(messagePool, 5, msgNet[1], msgNor[1], msgHigh[1], msgLow[0], msgNor[0]);
|
||||
VerifyPriorityQueueContent(queue, 2, msgLow[0], msgNor[0]);
|
||||
VerifyMsgQueueContent(messageQueue, 3, msgNor[1], msgHigh[1], msgNet[1]);
|
||||
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msgNet[1]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyAllMessagesContent(messagePool, 4, msgNor[1], msgHigh[1], msgLow[0], msgNor[0]);
|
||||
VerifyPriorityQueueContent(queue, 2, msgLow[0], msgNor[0]);
|
||||
VerifyMsgQueueContent(messageQueue, 2, msgNor[1], msgHigh[1]);
|
||||
|
||||
SuccessOrQuit(messageQueue.Dequeue(*msgHigh[1]), "MessageQueue::Dequeue() failed.\n");
|
||||
VerifyAllMessagesContent(messagePool, 3, msgNor[1], msgLow[0], msgNor[0]);
|
||||
VerifyPriorityQueueContent(queue, 2, msgLow[0], msgNor[0]);
|
||||
VerifyMsgQueueContent(messageQueue, 1, msgNor[1]);
|
||||
|
||||
SuccessOrQuit(queue.Dequeue(*msgLow[0]), "PriorityQueue::Dequeue() failed.\n");
|
||||
VerifyAllMessagesContent(messagePool, 2, msgNor[1], msgNor[0]);
|
||||
VerifyPriorityQueueContent(queue, 1, msgNor[0]);
|
||||
VerifyMsgQueueContent(messageQueue, 1, msgNor[1]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user