sched/mqueue: minor code tuning of message queue
1. remove unnecessary temporary variables 2. adjust the protection scope of the critical section Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
8da798926d
commit
be33d66c05
@ -55,8 +55,6 @@
|
||||
|
||||
void nxmq_free_msg(FAR struct mqueue_msg_s *mqmsg)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
/* If this is a generally available pre-allocated message,
|
||||
* then just put it back in the free list.
|
||||
*/
|
||||
@ -67,9 +65,7 @@ void nxmq_free_msg(FAR struct mqueue_msg_s *mqmsg)
|
||||
* list from interrupt handlers.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
sq_addlast((FAR sq_entry_t *)mqmsg, &g_msgfree);
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/* If this is a message pre-allocated for interrupts,
|
||||
@ -82,9 +78,7 @@ void nxmq_free_msg(FAR struct mqueue_msg_s *mqmsg)
|
||||
* list from interrupt handlers.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
sq_addlast((FAR sq_entry_t *)mqmsg, &g_msgfreeirq);
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/* Otherwise, deallocate it. Note: interrupt handlers
|
||||
|
@ -123,12 +123,10 @@ int nxmq_verify_receive(FAR struct mqueue_inode_s *msgq,
|
||||
int nxmq_wait_receive(FAR struct mqueue_inode_s *msgq,
|
||||
int oflags, FAR struct mqueue_msg_s **rcvmsg)
|
||||
{
|
||||
FAR struct tcb_s *rtcb;
|
||||
FAR struct mqueue_msg_s *newmsg;
|
||||
int ret;
|
||||
FAR struct tcb_s *rtcb;
|
||||
|
||||
DEBUGASSERT(rcvmsg != NULL);
|
||||
*rcvmsg = NULL; /* Assume failure */
|
||||
|
||||
#ifdef CONFIG_CANCELLATION_POINTS
|
||||
/* nxmq_wait_receive() is not a cancellation point, but it may be called
|
||||
@ -181,10 +179,9 @@ int nxmq_wait_receive(FAR struct mqueue_inode_s *msgq,
|
||||
* errno value (should be either EINTR or ETIMEDOUT).
|
||||
*/
|
||||
|
||||
ret = rtcb->errcode;
|
||||
if (ret != OK)
|
||||
if (rtcb->errcode != OK)
|
||||
{
|
||||
return -ret;
|
||||
return -rtcb->errcode;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -247,7 +244,6 @@ ssize_t nxmq_do_receive(FAR struct mqueue_inode_s *msgq,
|
||||
FAR char *ubuffer, unsigned int *prio)
|
||||
{
|
||||
FAR struct tcb_s *btcb;
|
||||
irqstate_t flags;
|
||||
ssize_t rcvmsglen;
|
||||
|
||||
/* Get the length of the message (also the return value) */
|
||||
@ -279,7 +275,6 @@ ssize_t nxmq_do_receive(FAR struct mqueue_inode_s *msgq,
|
||||
* messages can be sent from interrupt handlers.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
for (btcb = (FAR struct tcb_s *)g_waitingformqnotfull.head;
|
||||
btcb && btcb->msgwaitq != msgq;
|
||||
btcb = btcb->flink)
|
||||
@ -296,8 +291,6 @@ ssize_t nxmq_do_receive(FAR struct mqueue_inode_s *msgq,
|
||||
btcb->msgwaitq = NULL;
|
||||
msgq->nwaitnotfull--;
|
||||
up_unblock_task(btcb);
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/* Return the length of the message transferred to the user buffer */
|
||||
|
@ -79,7 +79,6 @@ ssize_t file_mq_receive(FAR struct file *mq, FAR char *msg, size_t msglen,
|
||||
irqstate_t flags;
|
||||
ssize_t ret;
|
||||
|
||||
inode = mq->f_inode;
|
||||
if (!inode)
|
||||
{
|
||||
return -EBADF;
|
||||
@ -108,7 +107,6 @@ ssize_t file_mq_receive(FAR struct file *mq, FAR char *msg, size_t msglen,
|
||||
/* Get the message from the message queue */
|
||||
|
||||
ret = nxmq_wait_receive(msgq, mq->f_oflags, &mqmsg);
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* Check if we got a message from the message queue. We might
|
||||
* not have a message if:
|
||||
@ -117,12 +115,13 @@ ssize_t file_mq_receive(FAR struct file *mq, FAR char *msg, size_t msglen,
|
||||
* - The wait was interrupted by a signal
|
||||
*/
|
||||
|
||||
if (ret >= 0)
|
||||
if (ret == OK)
|
||||
{
|
||||
DEBUGASSERT(mqmsg != NULL);
|
||||
ret = nxmq_do_receive(msgq, mqmsg, msg, prio);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -70,13 +70,12 @@
|
||||
int file_mq_send(FAR struct file *mq, FAR const char *msg, size_t msglen,
|
||||
unsigned int prio)
|
||||
{
|
||||
FAR struct mqueue_msg_s *mqmsg = NULL;
|
||||
FAR struct inode *inode = mq->f_inode;
|
||||
FAR struct mqueue_inode_s *msgq;
|
||||
FAR struct mqueue_msg_s *mqmsg;
|
||||
irqstate_t flags;
|
||||
int ret;
|
||||
|
||||
inode = mq->f_inode;
|
||||
if (!inode)
|
||||
{
|
||||
return -EBADF;
|
||||
@ -101,9 +100,7 @@ int file_mq_send(FAR struct file *mq, FAR const char *msg, size_t msglen,
|
||||
* non-FULL. This would fail with EAGAIN, EINTR, or ETIMEOUT.
|
||||
*/
|
||||
|
||||
mqmsg = NULL;
|
||||
flags = enter_critical_section();
|
||||
ret = OK;
|
||||
|
||||
if (!up_interrupt_context()) /* In an interrupt handler? */
|
||||
{
|
||||
@ -121,8 +118,7 @@ int file_mq_send(FAR struct file *mq, FAR const char *msg, size_t msglen,
|
||||
|
||||
/* ret can only be negative if nxmq_wait_send failed */
|
||||
|
||||
leave_critical_section(flags);
|
||||
if (ret >= 0)
|
||||
if (ret == OK)
|
||||
{
|
||||
/* Now allocate the message. */
|
||||
|
||||
@ -130,16 +126,6 @@ int file_mq_send(FAR struct file *mq, FAR const char *msg, size_t msglen,
|
||||
|
||||
/* Check if the message was successfully allocated */
|
||||
|
||||
ret = (mqmsg == NULL) ? -ENOMEM : OK;
|
||||
}
|
||||
|
||||
/* Check if we were able to get a message structure -- this can fail
|
||||
* either because we cannot send the message (and didn't bother trying
|
||||
* to allocate it) or because the allocation failed.
|
||||
*/
|
||||
|
||||
if (mqmsg != NULL)
|
||||
{
|
||||
/* The allocation was successful (implying that we can also send the
|
||||
* message). Perform the message send.
|
||||
*
|
||||
@ -149,9 +135,12 @@ int file_mq_send(FAR struct file *mq, FAR const char *msg, size_t msglen,
|
||||
* to be exceeded in that case.
|
||||
*/
|
||||
|
||||
ret = nxmq_do_send(msgq, mqmsg, msg, msglen, prio);
|
||||
ret = (mqmsg == NULL) ? -ENOMEM :
|
||||
nxmq_do_send(msgq, mqmsg, msg, msglen, prio);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,6 @@ int nxmq_verify_send(FAR struct mqueue_inode_s *msgq, int oflags,
|
||||
FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
|
||||
{
|
||||
FAR struct mqueue_msg_s *mqmsg;
|
||||
irqstate_t flags;
|
||||
|
||||
/* 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
|
||||
@ -154,9 +153,7 @@ FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
|
||||
* Disable interrupts -- we might be called from an interrupt handler.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
mqmsg = (FAR struct mqueue_msg_s *)sq_remfirst(&g_msgfree);
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* If we cannot a message from the free list, then we will have to
|
||||
* allocate one.
|
||||
@ -214,7 +211,6 @@ FAR struct mqueue_msg_s *nxmq_alloc_msg(void)
|
||||
int nxmq_wait_send(FAR struct mqueue_inode_s *msgq, int oflags)
|
||||
{
|
||||
FAR struct tcb_s *rtcb;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_CANCELLATION_POINTS
|
||||
/* nxmq_wait_send() is not a cancellation point, but may be called via
|
||||
@ -233,7 +229,11 @@ int nxmq_wait_send(FAR struct mqueue_inode_s *msgq, int oflags)
|
||||
|
||||
/* Verify that the queue is indeed full as the caller thinks */
|
||||
|
||||
if (msgq->nmsgs >= msgq->maxmsgs)
|
||||
/* Loop until there are fewer than max allowable messages in the
|
||||
* receiving message queue
|
||||
*/
|
||||
|
||||
while (msgq->nmsgs >= msgq->maxmsgs)
|
||||
{
|
||||
/* Should we block until there is sufficient space in the
|
||||
* message queue?
|
||||
@ -246,51 +246,36 @@ int nxmq_wait_send(FAR struct mqueue_inode_s *msgq, int oflags)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Yes... We will not return control until the message queue is
|
||||
* available or we receive a signal or at timeout occurs.
|
||||
/* Block until the message queue is no longer full.
|
||||
* When we are unblocked, we will try again
|
||||
*/
|
||||
|
||||
else
|
||||
rtcb = this_task();
|
||||
rtcb->msgwaitq = msgq;
|
||||
msgq->nwaitnotfull++;
|
||||
|
||||
/* Initialize the errcode used to communication wake-up error
|
||||
* conditions.
|
||||
*/
|
||||
|
||||
rtcb->errcode = OK;
|
||||
|
||||
/* Make sure this is not the idle task, descheduling that
|
||||
* isn't going to end well.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(NULL != rtcb->flink);
|
||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
|
||||
|
||||
/* When we resume at this point, either (1) the message queue
|
||||
* is no longer empty, or (2) the wait has been interrupted by
|
||||
* a signal. We can detect the latter case be examining the
|
||||
* per-task errno value (should be EINTR or ETIMEOUT).
|
||||
*/
|
||||
|
||||
if (rtcb->errcode != OK)
|
||||
{
|
||||
/* Loop until there are fewer than max allowable messages in the
|
||||
* receiving message queue
|
||||
*/
|
||||
|
||||
while (msgq->nmsgs >= msgq->maxmsgs)
|
||||
{
|
||||
/* Block until the message queue is no longer full.
|
||||
* When we are unblocked, we will try again
|
||||
*/
|
||||
|
||||
rtcb = this_task();
|
||||
rtcb->msgwaitq = msgq;
|
||||
msgq->nwaitnotfull++;
|
||||
|
||||
/* Initialize the errcode used to communication wake-up error
|
||||
* conditions.
|
||||
*/
|
||||
|
||||
rtcb->errcode = OK;
|
||||
|
||||
/* Make sure this is not the idle task, descheduling that
|
||||
* isn't going to end well.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(NULL != rtcb->flink);
|
||||
up_block_task(rtcb, TSTATE_WAIT_MQNOTFULL);
|
||||
|
||||
/* When we resume at this point, either (1) the message queue
|
||||
* is no longer empty, or (2) the wait has been interrupted by
|
||||
* a signal. We can detect the latter case be examining the
|
||||
* per-task errno value (should be EINTR or ETIMEOUT).
|
||||
*/
|
||||
|
||||
ret = rtcb->errcode;
|
||||
if (ret != OK)
|
||||
{
|
||||
return -ret;
|
||||
}
|
||||
}
|
||||
return -rtcb->errcode;
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,7 +310,6 @@ int nxmq_do_send(FAR struct mqueue_inode_s *msgq,
|
||||
FAR struct tcb_s *btcb;
|
||||
FAR struct mqueue_msg_s *next;
|
||||
FAR struct mqueue_msg_s *prev;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Construct the message header info */
|
||||
|
||||
@ -336,11 +320,8 @@ int nxmq_do_send(FAR struct mqueue_inode_s *msgq,
|
||||
|
||||
memcpy((FAR void *)mqmsg->mail, (FAR const void *)msg, msglen);
|
||||
|
||||
/* Insert the new message in the message queue */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Search the message list to find the location to insert the new
|
||||
/* Insert the new message in the message queue
|
||||
* Search the message list to find the location to insert the new
|
||||
* message. Each is list is maintained in ascending priority order.
|
||||
*/
|
||||
|
||||
@ -367,8 +348,6 @@ int nxmq_do_send(FAR struct mqueue_inode_s *msgq,
|
||||
nxmq_pollnotify(msgq, POLLIN);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* Check if we need to notify any tasks that are attached to the
|
||||
* message queue
|
||||
*/
|
||||
@ -398,7 +377,6 @@ int nxmq_do_send(FAR struct mqueue_inode_s *msgq,
|
||||
|
||||
/* Check if any tasks are waiting for the MQ not empty event. */
|
||||
|
||||
flags = enter_critical_section();
|
||||
if (msgq->nwaitnotempty > 0)
|
||||
{
|
||||
/* Find the highest priority task that is waiting for
|
||||
@ -423,6 +401,5 @@ int nxmq_do_send(FAR struct mqueue_inode_s *msgq,
|
||||
up_unblock_task(btcb);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
return OK;
|
||||
}
|
||||
|
@ -145,7 +145,6 @@ ssize_t file_mq_timedreceive(FAR struct file *mq, FAR char *msg,
|
||||
irqstate_t flags;
|
||||
int ret;
|
||||
|
||||
inode = mq->f_inode;
|
||||
if (!inode)
|
||||
{
|
||||
return -EBADF;
|
||||
@ -188,23 +187,23 @@ ssize_t file_mq_timedreceive(FAR struct file *mq, FAR char *msg,
|
||||
* disabled here so that this time stays valid until the wait begins.
|
||||
*/
|
||||
|
||||
int result = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||
ret = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||
|
||||
/* If the time has already expired and the message queue is empty,
|
||||
* return immediately.
|
||||
*/
|
||||
|
||||
if (result == OK && ticks <= 0)
|
||||
if (ret == OK && ticks <= 0)
|
||||
{
|
||||
result = ETIMEDOUT;
|
||||
ret = ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Handle any time-related errors */
|
||||
|
||||
if (result != OK)
|
||||
if (ret != OK)
|
||||
{
|
||||
leave_critical_section(flags);
|
||||
return -result;
|
||||
ret = -ret;
|
||||
goto errout_in_critical_section;
|
||||
}
|
||||
|
||||
/* Start the watchdog */
|
||||
@ -222,10 +221,6 @@ ssize_t file_mq_timedreceive(FAR struct file *mq, FAR char *msg,
|
||||
|
||||
wd_cancel(&rtcb->waitdog);
|
||||
|
||||
/* We can now restore interrupts */
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* Check if we got a message from the message queue. We might
|
||||
* not have a message if:
|
||||
*
|
||||
@ -234,12 +229,17 @@ ssize_t file_mq_timedreceive(FAR struct file *mq, FAR char *msg,
|
||||
* - The watchdog timeout expired
|
||||
*/
|
||||
|
||||
if (ret >= 0)
|
||||
if (ret == OK)
|
||||
{
|
||||
DEBUGASSERT(mqmsg != NULL);
|
||||
ret = nxmq_do_receive(msgq, mqmsg, msg, prio);
|
||||
}
|
||||
|
||||
/* We can now restore interrupts */
|
||||
|
||||
errout_in_critical_section:
|
||||
leave_critical_section(flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -146,16 +146,14 @@ int file_mq_timedsend(FAR struct file *mq, FAR const char *msg,
|
||||
size_t msglen, unsigned int prio,
|
||||
FAR const struct timespec *abstime)
|
||||
{
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
FAR struct inode *inode = mq->f_inode;
|
||||
FAR struct tcb_s *rtcb = this_task();
|
||||
FAR struct mqueue_inode_s *msgq;
|
||||
FAR struct mqueue_msg_s *mqmsg;
|
||||
irqstate_t flags;
|
||||
sclock_t ticks;
|
||||
int result;
|
||||
int ret;
|
||||
|
||||
inode = mq->f_inode;
|
||||
if (!inode)
|
||||
{
|
||||
return -EBADF;
|
||||
@ -173,6 +171,10 @@ int file_mq_timedsend(FAR struct file *mq, FAR const char *msg,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Disable interruption */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Pre-allocate a message structure */
|
||||
|
||||
mqmsg = nxmq_alloc_msg();
|
||||
@ -182,7 +184,8 @@ int file_mq_timedsend(FAR struct file *mq, FAR const char *msg,
|
||||
* errno value.
|
||||
*/
|
||||
|
||||
return -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto errout_in_critical_section;
|
||||
}
|
||||
|
||||
/* OpenGroup.org: "Under no circumstance shall the operation fail with a
|
||||
@ -205,7 +208,7 @@ int file_mq_timedsend(FAR struct file *mq, FAR const char *msg,
|
||||
* Currently nxmq_do_send() always returns OK.
|
||||
*/
|
||||
|
||||
return nxmq_do_send(msgq, mqmsg, msg, msglen, prio);
|
||||
goto out_send_message;
|
||||
}
|
||||
|
||||
/* The message queue is full... We are going to wait. Now we must have a
|
||||
@ -215,7 +218,8 @@ int file_mq_timedsend(FAR struct file *mq, FAR const char *msg,
|
||||
if (!abstime || abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
|
||||
{
|
||||
ret = -EINVAL;
|
||||
goto errout_with_mqmsg;
|
||||
nxmq_free_msg(mqmsg);
|
||||
goto errout_in_critical_section;
|
||||
}
|
||||
|
||||
/* We are not in an interrupt handler and the message queue is full.
|
||||
@ -225,23 +229,22 @@ int file_mq_timedsend(FAR struct file *mq, FAR const char *msg,
|
||||
* disabled here so that this time stays valid until the wait begins.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
result = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||
ret = clock_abstime2ticks(CLOCK_REALTIME, abstime, &ticks);
|
||||
|
||||
/* If the time has already expired and the message queue is empty,
|
||||
* return immediately.
|
||||
*/
|
||||
|
||||
if (result == OK && ticks <= 0)
|
||||
if (ret == OK && ticks <= 0)
|
||||
{
|
||||
result = ETIMEDOUT;
|
||||
ret = ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Handle any time-related errors */
|
||||
|
||||
if (result != OK)
|
||||
if (ret != OK)
|
||||
{
|
||||
ret = -result;
|
||||
ret = -ret;
|
||||
goto errout_in_critical_section;
|
||||
}
|
||||
|
||||
@ -261,26 +264,19 @@ int file_mq_timedsend(FAR struct file *mq, FAR const char *msg,
|
||||
|
||||
/* Check if nxmq_wait_send() failed */
|
||||
|
||||
if (ret < 0)
|
||||
if (ret == OK)
|
||||
{
|
||||
/* nxmq_wait_send() failed. */
|
||||
/* If any of the above failed, set the errno. Otherwise, there should
|
||||
* be space for another message in the message queue. NOW we can
|
||||
* allocate the message structure.
|
||||
*
|
||||
* Currently nxmq_do_send() always returns OK.
|
||||
*/
|
||||
|
||||
goto errout_in_critical_section;
|
||||
out_send_message:
|
||||
ret = nxmq_do_send(msgq, mqmsg, msg, msglen, prio);
|
||||
}
|
||||
|
||||
/* That is the end of the atomic operations */
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* If any of the above failed, set the errno. Otherwise, there should
|
||||
* be space for another message in the message queue. NOW we can allocate
|
||||
* the message structure.
|
||||
*
|
||||
* Currently nxmq_do_send() always returns OK.
|
||||
*/
|
||||
|
||||
return nxmq_do_send(msgq, mqmsg, msg, msglen, prio);
|
||||
|
||||
/* Exit here with (1) the scheduler locked, (2) a message allocated, (3) a
|
||||
* wdog allocated, and (4) interrupts disabled.
|
||||
*/
|
||||
@ -288,12 +284,6 @@ int file_mq_timedsend(FAR struct file *mq, FAR const char *msg,
|
||||
errout_in_critical_section:
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* Exit here with (1) the scheduler locked and 2) a message allocated. The
|
||||
* error code is in 'result'
|
||||
*/
|
||||
|
||||
errout_with_mqmsg:
|
||||
nxmq_free_msg(mqmsg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user