diff --git a/sched/mqueue/mq_msgfree.c b/sched/mqueue/mq_msgfree.c index f53f8e9962d..f911ce7a0e6 100644 --- a/sched/mqueue/mq_msgfree.c +++ b/sched/mqueue/mq_msgfree.c @@ -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 diff --git a/sched/mqueue/mq_rcvinternal.c b/sched/mqueue/mq_rcvinternal.c index a7b278822b2..f369e541e66 100644 --- a/sched/mqueue/mq_rcvinternal.c +++ b/sched/mqueue/mq_rcvinternal.c @@ -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 */ diff --git a/sched/mqueue/mq_receive.c b/sched/mqueue/mq_receive.c index 1bd1c86546c..ebe4209c239 100644 --- a/sched/mqueue/mq_receive.c +++ b/sched/mqueue/mq_receive.c @@ -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; } diff --git a/sched/mqueue/mq_send.c b/sched/mqueue/mq_send.c index 320d908ea78..730e49b2620 100644 --- a/sched/mqueue/mq_send.c +++ b/sched/mqueue/mq_send.c @@ -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; } diff --git a/sched/mqueue/mq_sndinternal.c b/sched/mqueue/mq_sndinternal.c index 6ae163db9f6..32ae2054274 100644 --- a/sched/mqueue/mq_sndinternal.c +++ b/sched/mqueue/mq_sndinternal.c @@ -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; } diff --git a/sched/mqueue/mq_timedreceive.c b/sched/mqueue/mq_timedreceive.c index 72dc8291c28..9e3f9b8582d 100644 --- a/sched/mqueue/mq_timedreceive.c +++ b/sched/mqueue/mq_timedreceive.c @@ -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; } diff --git a/sched/mqueue/mq_timedsend.c b/sched/mqueue/mq_timedsend.c index a26174927d9..2d9003f6137 100644 --- a/sched/mqueue/mq_timedsend.c +++ b/sched/mqueue/mq_timedsend.c @@ -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; }