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 <anc...@xiaomi.com> AuthorDate: Wed Jun 8 22:42:01 2022 +0800 sched/mqueue: replace inline linklist to improve performance Signed-off-by: chao.an <anc...@xiaomi.com> --- 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