This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 7c12e5281e sched/mqueue: replace inline linklist to improve performance
7c12e5281e is described below
commit 7c12e5281e9ae098026ba90ab9c0c6ca5b2f7a3d
Author: chao.an <[email protected]>
AuthorDate: Wed Jun 8 22:42:01 2022 +0800
sched/mqueue: replace inline linklist to improve performance
Signed-off-by: chao.an <[email protected]>
---
include/nuttx/mqueue.h | 3 +-
sched/mqueue/mq_initialize.c | 55 +++++++++------------------------
sched/mqueue/mq_msgfree.c | 5 ++-
sched/mqueue/mq_msgqalloc.c | 2 +-
sched/mqueue/mq_msgqfree.c | 13 ++++----
sched/mqueue/mq_rcvinternal.c | 4 +--
sched/mqueue/mq_sndinternal.c | 70 ++++++++++++++++++++----------------------
sched/mqueue/mq_timedreceive.c | 2 +-
sched/mqueue/mqueue.h | 18 +++++------
9 files changed, 71 insertions(+), 101 deletions(-)
diff --git a/include/nuttx/mqueue.h b/include/nuttx/mqueue.h
index bcd50935df..a25ff84b03 100644
--- a/include/nuttx/mqueue.h
+++ b/include/nuttx/mqueue.h
@@ -29,6 +29,7 @@
#include <nuttx/compiler.h>
#include <nuttx/fs/fs.h>
#include <nuttx/signal.h>
+#include <nuttx/list.h>
#include <sys/types.h>
#include <stdint.h>
@@ -87,7 +88,7 @@
struct mqueue_inode_s
{
FAR struct inode *inode; /* Containing inode */
- sq_queue_t msglist; /* Prioritized message list */
+ struct list_node msglist; /* Prioritized message list */
int16_t maxmsgs; /* Maximum number of messages in the queue */
int16_t nmsgs; /* Number of message in the queue */
int16_t nwaitnotfull; /* Number tasks waiting for not full */
diff --git a/sched/mqueue/mq_initialize.c b/sched/mqueue/mq_initialize.c
index 2c0febe111..ee6570e1d6 100644
--- a/sched/mqueue/mq_initialize.c
+++ b/sched/mqueue/mq_initialize.c
@@ -25,7 +25,6 @@
#include <nuttx/config.h>
#include <stdint.h>
-#include <queue.h>
#include <nuttx/kmalloc.h>
#include "mqueue/mqueue.h"
@@ -39,29 +38,13 @@
* item.
*/
-sq_queue_t g_msgfree;
+struct list_node g_msgfree = LIST_INITIAL_VALUE(g_msgfree);
/* The g_msgfreeInt is a list of messages that are reserved for use by
* interrupt handlers.
*/
-sq_queue_t g_msgfreeirq;
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/* g_msgalloc is a pointer to the start of the allocated block of
- * messages.
- */
-
-static struct mqueue_msg_s *g_msgalloc;
-
-/* g_msgfreeirqalloc is a pointer to the start of the allocated block of
- * messages.
- */
-
-static struct mqueue_msg_s *g_msgfreeirqalloc;
+struct list_node g_msgfreeirq = LIST_INITIAL_VALUE(g_msgfreeirq);
/****************************************************************************
* Private Functions
@@ -78,13 +61,13 @@ static struct mqueue_msg_s *g_msgfreeirqalloc;
*
****************************************************************************/
-static struct mqueue_msg_s *
-mq_msgblockalloc(FAR sq_queue_t *queue, uint16_t nmsgs,
+static void
+mq_msgblockalloc(FAR struct list_node *list, uint16_t nmsgs,
uint8_t alloc_type)
{
- struct mqueue_msg_s *mqmsgblock;
+ FAR struct mqueue_msg_s *mqmsgblock;
- /* The g_msgfree must be loaded at initialization time to hold the
+ /* The list must be loaded at initialization time to hold the
* configured number of messages.
*/
@@ -93,17 +76,14 @@ mq_msgblockalloc(FAR sq_queue_t *queue, uint16_t nmsgs,
if (mqmsgblock)
{
- struct mqueue_msg_s *mqmsg = mqmsgblock;
- int i;
-
+ int i;
for (i = 0; i < nmsgs; i++)
{
- mqmsg->type = alloc_type;
- sq_addlast((FAR sq_entry_t *)mqmsg++, queue);
+ mqmsgblock->type = alloc_type;
+ list_add_tail(list, &mqmsgblock->node);
+ mqmsgblock++;
}
}
-
- return mqmsgblock;
}
/****************************************************************************
@@ -128,22 +108,15 @@ mq_msgblockalloc(FAR sq_queue_t *queue, uint16_t nmsgs,
void nxmq_initialize(void)
{
- /* Initialize the message free lists */
-
- sq_init(&g_msgfree);
- sq_init(&g_msgfreeirq);
-
/* Allocate a block of messages for general use */
- g_msgalloc =
- mq_msgblockalloc(&g_msgfree, CONFIG_PREALLOC_MQ_MSGS,
- MQ_ALLOC_FIXED);
+ mq_msgblockalloc(&g_msgfree, CONFIG_PREALLOC_MQ_MSGS,
+ MQ_ALLOC_FIXED);
/* Allocate a block of messages for use exclusively by
* interrupt handlers
*/
- g_msgfreeirqalloc =
- mq_msgblockalloc(&g_msgfreeirq, CONFIG_PREALLOC_MQ_IRQ_MSGS,
- MQ_ALLOC_IRQ);
+ mq_msgblockalloc(&g_msgfreeirq, CONFIG_PREALLOC_MQ_IRQ_MSGS,
+ MQ_ALLOC_IRQ);
}
diff --git a/sched/mqueue/mq_msgfree.c b/sched/mqueue/mq_msgfree.c
index f911ce7a0e..bc8fe3c784 100644
--- a/sched/mqueue/mq_msgfree.c
+++ b/sched/mqueue/mq_msgfree.c
@@ -25,7 +25,6 @@
#include <nuttx/config.h>
#include <assert.h>
-#include <queue.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
@@ -65,7 +64,7 @@ void nxmq_free_msg(FAR struct mqueue_msg_s *mqmsg)
* list from interrupt handlers.
*/
- sq_addlast((FAR sq_entry_t *)mqmsg, &g_msgfree);
+ list_add_tail(&g_msgfree, &mqmsg->node);
}
/* If this is a message pre-allocated for interrupts,
@@ -78,7 +77,7 @@ void nxmq_free_msg(FAR struct mqueue_msg_s *mqmsg)
* list from interrupt handlers.
*/
- sq_addlast((FAR sq_entry_t *)mqmsg, &g_msgfreeirq);
+ list_add_tail(&g_msgfreeirq, &mqmsg->node);
}
/* Otherwise, deallocate it. Note: interrupt handlers
diff --git a/sched/mqueue/mq_msgqalloc.c b/sched/mqueue/mq_msgqalloc.c
index 69372d1802..a2faf54788 100644
--- a/sched/mqueue/mq_msgqalloc.c
+++ b/sched/mqueue/mq_msgqalloc.c
@@ -86,7 +86,7 @@ int nxmq_alloc_msgq(FAR struct mq_attr *attr,
{
/* Initialize the new named message queue */
- sq_init(&msgq->msglist);
+ list_initialize(&msgq->msglist);
if (attr)
{
msgq->maxmsgs = (int16_t)attr->mq_maxmsg;
diff --git a/sched/mqueue/mq_msgqfree.c b/sched/mqueue/mq_msgqfree.c
index 2b99cc86dd..c281f5aa51 100644
--- a/sched/mqueue/mq_msgqfree.c
+++ b/sched/mqueue/mq_msgqfree.c
@@ -52,19 +52,18 @@
void nxmq_free_msgq(FAR struct mqueue_inode_s *msgq)
{
- FAR struct mqueue_msg_s *curr;
- FAR struct mqueue_msg_s *next;
+ FAR struct mqueue_msg_s *entry;
+ FAR struct mqueue_msg_s *tmp;
/* Deallocate any stranded messages in the message queue. */
- curr = (FAR struct mqueue_msg_s *)msgq->msglist.head;
- while (curr)
+ list_for_every_entry_safe(&msgq->msglist, entry,
+ tmp, struct mqueue_msg_s, node)
{
/* Deallocate the message structure. */
- next = curr->next;
- nxmq_free_msg(curr);
- curr = next;
+ list_delete(&entry->node);
+ nxmq_free_msg(entry);
}
/* Then deallocate the message queue itself */
diff --git a/sched/mqueue/mq_rcvinternal.c b/sched/mqueue/mq_rcvinternal.c
index f8c56e9524..0187255d1e 100644
--- a/sched/mqueue/mq_rcvinternal.c
+++ b/sched/mqueue/mq_rcvinternal.c
@@ -155,8 +155,8 @@ int nxmq_wait_receive(FAR struct mqueue_inode_s *msgq,
/* Get the message from the head of the queue */
- while ((newmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&msgq->msglist))
- == NULL)
+ while ((newmsg = (FAR struct mqueue_msg_s *)
+ list_remove_head(&msgq->msglist)) == NULL)
{
/* The queue is empty! Should we block until there the above condition
* has been satisfied?
diff --git a/sched/mqueue/mq_sndinternal.c b/sched/mqueue/mq_sndinternal.c
index d63716207f..1a53c6d287 100644
--- a/sched/mqueue/mq_sndinternal.c
+++ b/sched/mqueue/mq_sndinternal.c
@@ -136,43 +136,34 @@ int nxmq_verify_send(FAR FAR struct file *mq, FAR const
char *msg,
FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
{
- FAR struct mqueue_msg_s *mqmsg;
+ FAR struct list_node *mqmsg;
- /* If we were called from an interrupt handler, then try to get the message
- * from generally available list of messages. If this fails, then try the
- * list of messages reserved for interrupt handlers
- */
+ /* Try to get the message from the generally available free list. */
- if (up_interrupt_context())
+ mqmsg = list_remove_head(&g_msgfree);
+ if (mqmsg == NULL)
{
- /* Try the general free list */
+ /* If we were called from an interrupt handler, then try to get the
+ * message from generally available list of messages. If this fails,
+ * then try the list of messages reserved for interrupt handlers
+ */
- mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree);
- if (mqmsg == NULL)
+ if (up_interrupt_context())
{
/* Try the free list reserved for interrupt handlers */
- mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfreeirq);
+ mqmsg = list_remove_head(&g_msgfreeirq);
}
- }
-
- /* We were not called from an interrupt handler. */
-
- else
- {
- /* Try to get the message from the generally available free list.
- * Disable interrupts -- we might be called from an interrupt handler.
- */
- mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree);
-
- /* If we cannot a message from the free list, then we will have to
- * allocate one.
- */
+ /* We were not called from an interrupt handler. */
- if (mqmsg == NULL)
+ else
{
- mqmsg = (FAR struct mqueue_msg_s *)
+ /* If we cannot a message from the free list, then we will have to
+ * allocate one.
+ */
+
+ mqmsg = (FAR struct list_node *)
kmm_malloc((sizeof (struct mqueue_msg_s)));
/* Check if we allocated the message */
@@ -183,12 +174,12 @@ FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
* allocated.
*/
- mqmsg->type = MQ_ALLOC_DYN;
+ ((FAR struct mqueue_msg_s *)mqmsg)->type = MQ_ALLOC_DYN;
}
}
}
- return mqmsg;
+ return (FAR struct mqueue_msg_s *)mqmsg;
}
/****************************************************************************
@@ -318,9 +309,9 @@ int nxmq_do_send(FAR struct mqueue_inode_s *msgq,
FAR struct mqueue_msg_s *mqmsg,
FAR const char *msg, size_t msglen, unsigned int prio)
{
- FAR struct tcb_s *btcb;
+ FAR struct mqueue_msg_s *prev = NULL;
FAR struct mqueue_msg_s *next;
- FAR struct mqueue_msg_s *prev;
+ FAR struct tcb_s *btcb;
/* Construct the message header info */
@@ -336,20 +327,27 @@ int nxmq_do_send(FAR struct mqueue_inode_s *msgq,
* message. Each is list is maintained in ascending priority order.
*/
- for (prev = NULL, next = (FAR struct mqueue_msg_s *)msgq->msglist.head;
- next && prio <= next->priority;
- prev = next, next = next->next);
+ list_for_every_entry(&msgq->msglist, next, struct mqueue_msg_s, node)
+ {
+ if (prio > next->priority)
+ {
+ break;
+ }
+ else
+ {
+ prev = next;
+ }
+ }
/* Add the message at the right place */
if (prev)
{
- sq_addafter((FAR sq_entry_t *)prev, (FAR sq_entry_t *)mqmsg,
- &msgq->msglist);
+ list_add_after(&prev->node, &mqmsg->node);
}
else
{
- sq_addfirst((FAR sq_entry_t *)mqmsg, &msgq->msglist);
+ list_add_head(&msgq->msglist, &mqmsg->node);
}
/* Increment the count of messages in the queue */
diff --git a/sched/mqueue/mq_timedreceive.c b/sched/mqueue/mq_timedreceive.c
index 71460f65ec..b9622e6ca0 100644
--- a/sched/mqueue/mq_timedreceive.c
+++ b/sched/mqueue/mq_timedreceive.c
@@ -173,7 +173,7 @@ ssize_t file_mq_timedreceive(FAR struct file *mq, FAR char
*msg,
* will not need to start timer.
*/
- if (msgq->msglist.head == NULL)
+ if (list_is_empty(&msgq->msglist))
{
sclock_t ticks;
diff --git a/sched/mqueue/mqueue.h b/sched/mqueue/mqueue.h
index ab28437fb2..1eed43d0ba 100644
--- a/sched/mqueue/mqueue.h
+++ b/sched/mqueue/mqueue.h
@@ -62,15 +62,15 @@ enum mqalloc_e
struct mqueue_msg_s
{
- FAR struct mqueue_msg_s *next; /* Forward link to next message */
- uint8_t type; /* (Used to manage allocations) */
- uint8_t priority; /* priority of message */
+ struct list_node node; /* Link node to message */
+ uint8_t type; /* (Used to manage allocations) */
+ uint8_t priority; /* Priority of message */
#if MQ_MAX_BYTES < 256
- uint8_t msglen; /* Message data length */
+ uint8_t msglen; /* Message data length */
#else
- uint16_t msglen; /* Message data length */
+ uint16_t msglen; /* Message data length */
#endif
- char mail[MQ_MAX_BYTES]; /* Message data */
+ char mail[MQ_MAX_BYTES]; /* Message data */
};
/********************************************************************************
@@ -89,13 +89,13 @@ extern "C"
* The number of messages in this list is a system configuration item.
*/
-EXTERN sq_queue_t g_msgfree;
+EXTERN struct list_node g_msgfree;
-/* The g_msgfreeInt is a list of messages that are reserved for use by
+/* The g_msgfreeirq is a list of messages that are reserved for use by
* interrupt handlers.
*/
-EXTERN sq_queue_t g_msgfreeirq;
+EXTERN struct list_node g_msgfreeirq;
/********************************************************************************
* Public Function Prototypes