sched/semaphore: sem_trywait() modifies the errno value and, hence, should not be used within the OS. Use nxsem_trywait() instead.

This commit is contained in:
Gregory Nutt 2017-10-05 07:59:06 -06:00
parent 29b5b3667f
commit 7cc63f90d9
16 changed files with 111 additions and 34 deletions

View File

@ -45,6 +45,7 @@
#include <debug.h> #include <debug.h>
#include <string.h> #include <string.h>
#include <nuttx/semaphore.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h> #include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#include <nuttx/wireless/ieee802154/xbee.h> #include <nuttx/wireless/ieee802154/xbee.h>
@ -149,7 +150,7 @@ int xbee_dataind_alloc(FAR struct xbee_priv_s *priv,
* The MAC is already locked, so there shouldn't be any other conflicting calls * The MAC is already locked, so there shouldn't be any other conflicting calls
*/ */
ret = sem_trywait(&priv->dataind_sem); ret = nxsem_trywait(&priv->dataind_sem);
if (ret == OK) if (ret == OK)
{ {

View File

@ -49,6 +49,7 @@
#include "xbee_mac.h" #include "xbee_mac.h"
#include "xbee_notif.h" #include "xbee_notif.h"
#include <nuttx/semaphore.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h> #include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#include <nuttx/wireless/ieee802154/xbee.h> #include <nuttx/wireless/ieee802154/xbee.h>
@ -154,7 +155,7 @@ int xbee_notif_alloc(FAR struct xbee_priv_s *priv,
* The MAC is already locked, so there shouldn't be any other conflicting calls * The MAC is already locked, so there shouldn't be any other conflicting calls
*/ */
ret = sem_trywait(&priv->notif_sem); ret = nxsem_trywait(&priv->notif_sem);
if (ret == OK) if (ret == OK)
{ {

View File

@ -70,7 +70,7 @@
* task. Following a call to sem_open() with the semaphore name, the task * task. Following a call to sem_open() with the semaphore name, the task
* may reference the semaphore associated with name using the address * may reference the semaphore associated with name using the address
* returned by this call. The semaphore may be used in subsequent calls * returned by this call. The semaphore may be used in subsequent calls
* to nxsem_wait(), sem_trywait(), and sem_post(). The semaphore remains * to sem_wait(), sem_trywait(), and sem_post(). The semaphore remains
* usable until the semaphore is closed by a successful call to sem_close(). * usable until the semaphore is closed by a successful call to sem_close().
* *
* If a task makes multiple calls to sem_open() with the same name, then * If a task makes multiple calls to sem_open() with the same name, then

View File

@ -173,13 +173,39 @@ int nxsem_destroy (FAR sem_t *sem);
* returned on success. A negated errno value is returned on failure. * returned on success. A negated errno value is returned on failure.
* Possible returned errors: * Possible returned errors:
* *
* - EINVAL: Invalid attempt to get the semaphore * EINVAL - Invalid attempt to get the semaphore
* - EINTR: The wait was interrupted by the receipt of a signal. * EINTR - The wait was interrupted by the receipt of a signal.
* *
****************************************************************************/ ****************************************************************************/
int nxsem_wait(FAR sem_t *sem); int nxsem_wait(FAR sem_t *sem);
/****************************************************************************
* Name: nxsem_trywait
*
* Description:
* This function locks the specified semaphore only if the semaphore is
* currently not locked. Otherwise, it locks the semaphore. In either
* case, the call returns without blocking.
*
* Parameters:
* sem - the semaphore descriptor
*
* Return Value:
* This is an internal OS interface and should not be used by applications.
* It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
*
* EINVAL - Invalid attempt to get the semaphore
* EAGAIN - The semaphore is not available.
*
* Assumptions:
*
****************************************************************************/
int nxsem_trywait(FAR sem_t *sem);
/**************************************************************************** /****************************************************************************
* Name: nxsem_timedwait * Name: nxsem_timedwait
* *

View File

@ -112,12 +112,12 @@ int nxsem_init(FAR sem_t *sem, int pshared, unsigned int value)
* Description: * Description:
* This function initializes the UNAMED semaphore sem. Following a * This function initializes the UNAMED semaphore sem. Following a
* successful call to sem_init(), the semaphore may be used in subsequent * successful call to sem_init(), the semaphore may be used in subsequent
* calls to sem_wait(), nxsem_post(), and sem_trywait(). The semaphore * calls to sem_wait(), sem_post(), and sem_trywait(). The semaphore
* remains usable until it is destroyed. * remains usable until it is destroyed.
* *
* Only sem itself may be used for performing synchronization. The result * Only sem itself may be used for performing synchronization. The result
* of referring to copies of sem in calls to sem_wait(), sem_trywait(), * of referring to copies of sem in calls to sem_wait(), sem_trywait(),
* nxsem_post(), and sem_destroy() is undefined. * sem_post(), and sem_destroy() is undefined.
* *
* Parameters: * Parameters:
* sem - Semaphore to be initialized * sem - Semaphore to be initialized

View File

@ -270,7 +270,7 @@ FAR struct iob_s *iob_tryalloc(bool throttled)
g_iob_freelist = iob->io_flink; g_iob_freelist = iob->io_flink;
/* Take a semaphore count. Note that we cannot do this in /* Take a semaphore count. Note that we cannot do this in
* in the orthodox way by calling nxsem_wait() or sem_trywait() * in the orthodox way by calling nxsem_wait() or nxsem_trywait()
* because this function may be called from an interrupt * because this function may be called from an interrupt
* handler. Fortunately we know at at least one free buffer * handler. Fortunately we know at at least one free buffer
* so a simple decrement is all that is needed. * so a simple decrement is all that is needed.

View File

@ -245,7 +245,7 @@ FAR struct iob_qentry_s *iob_tryalloc_qentry(void)
g_iob_freeqlist = iobq->qe_flink; g_iob_freeqlist = iobq->qe_flink;
/* Take a semaphore count. Note that we cannot do this in /* Take a semaphore count. Note that we cannot do this in
* in the orthodox way by calling nxsem_wait() or sem_trywait() * in the orthodox way by calling nxsem_wait() or nxsem_trywait()
* because this function may be called from an interrupt * because this function may be called from an interrupt
* handler. Fortunately we know at at least one free buffer * handler. Fortunately we know at at least one free buffer
* so a simple decrement is all that is needed. * so a simple decrement is all that is needed.

View File

@ -108,6 +108,7 @@ void mm_seminitialize(FAR struct mm_heap_s *heap)
int mm_trysemaphore(FAR struct mm_heap_s *heap) int mm_trysemaphore(FAR struct mm_heap_s *heap)
{ {
pid_t my_pid = getpid(); pid_t my_pid = getpid();
int ret;
/* Do I already have the semaphore? */ /* Do I already have the semaphore? */
@ -122,9 +123,10 @@ int mm_trysemaphore(FAR struct mm_heap_s *heap)
{ {
/* Try to take the semaphore (perhaps waiting) */ /* Try to take the semaphore (perhaps waiting) */
if (sem_trywait(&heap->mm_semaphore) != 0) ret = nxsem_trywait(&heap->mm_semaphore);
if (ret < 0)
{ {
return ERROR; return ret;
} }
/* We have it. Claim the stak and return */ /* We have it. Claim the stak and return */

View File

@ -45,6 +45,8 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <nuttx/semaphore.h>
#include "pthread/pthread.h" #include "pthread/pthread.h"
/**************************************************************************** /****************************************************************************
@ -150,8 +152,8 @@ int pthread_sem_trytake(sem_t *sem)
{ {
/* Try to take the semaphore */ /* Try to take the semaphore */
int status = sem_trywait(sem); int status = nxsem_trywait(sem);
ret = status < 0 ? get_errno() : OK; ret = ret < 0 ? -ret : OK;
} }
return ret; return ret;

View File

@ -46,6 +46,7 @@
#include <nuttx/irq.h> #include <nuttx/irq.h>
#include <nuttx/sched.h> #include <nuttx/sched.h>
#include <nuttx/semaphore.h>
#include "sched/sched.h" #include "sched/sched.h"
#include "pthread/pthread.h" #include "pthread/pthread.h"
@ -269,10 +270,10 @@ int pthread_mutex_trytake(FAR struct pthread_mutex_s *mutex)
{ {
/* Try to take the semaphore underlying the mutex */ /* Try to take the semaphore underlying the mutex */
ret = sem_trywait(&mutex->sem); ret = nxsem_trywait(&mutex->sem);
if (ret < OK) if (ret < 0)
{ {
ret = get_errno(); ret = -ret;
} }
else else
{ {

View File

@ -46,6 +46,7 @@
#include <nuttx/sched.h> #include <nuttx/sched.h>
#include <nuttx/cancelpt.h> #include <nuttx/cancelpt.h>
#include <nuttx/semaphore.h>
#include "sched/sched.h" #include "sched/sched.h"
#include "group/group.h" #include "group/group.h"
@ -241,7 +242,7 @@ pid_t waitpid(pid_t pid, int *stat_loc, int options)
{ {
/* Don't wait if status is not available */ /* Don't wait if status is not available */
ret = sem_trywait(&group->tg_exitsem); ret = nxsem_trywait(&group->tg_exitsem);
group_delwaiter(group); group_delwaiter(group);
if (ret < 0) if (ret < 0)

View File

@ -50,6 +50,7 @@
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/clock.h> #include <nuttx/clock.h>
#include <nuttx/wdog.h> #include <nuttx/wdog.h>
#include <nuttx/semaphore.h>
#include "sched/sched.h" #include "sched/sched.h"
#include "semaphore/semaphore.h" #include "semaphore/semaphore.h"
@ -73,7 +74,7 @@
* in any event. * in any event.
* delay - Ticks to wait from the start time until the semaphore is * delay - Ticks to wait from the start time until the semaphore is
* posted. If ticks is zero, then this function is equivalent * posted. If ticks is zero, then this function is equivalent
* to sem_trywait(). * to nxsem_trywait().
* *
* Return Value: * Return Value:
* This is an internal OS interface, not available to applications, and * This is an internal OS interface, not available to applications, and
@ -116,7 +117,7 @@ int nxsem_tickwait(FAR sem_t *sem, systime_t start, uint32_t delay)
/* Try to take the semaphore without waiting. */ /* Try to take the semaphore without waiting. */
ret = sem_trywait(sem); ret = nxsem_trywait(sem);
if (ret == OK) if (ret == OK)
{ {
/* We got it! */ /* We got it! */
@ -130,9 +131,8 @@ int nxsem_tickwait(FAR sem_t *sem, systime_t start, uint32_t delay)
if (delay == 0) if (delay == 0)
{ {
/* Return the errno from sem_trywait() */ /* Return the errno from nxsem_trywait() */
ret = -get_errno();
goto errout_with_irqdisabled; goto errout_with_irqdisabled;
} }

View File

@ -50,6 +50,7 @@
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/wdog.h> #include <nuttx/wdog.h>
#include <nuttx/cancelpt.h> #include <nuttx/cancelpt.h>
#include <nuttx/semaphore.h>
#include "sched/sched.h" #include "sched/sched.h"
#include "clock/clock.h" #include "clock/clock.h"
@ -146,7 +147,7 @@ int nxsem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
/* Try to take the semaphore without waiting. */ /* Try to take the semaphore without waiting. */
ret = sem_trywait(sem); ret = nxsem_trywait(sem);
if (ret == OK) if (ret == OK)
{ {
/* We got it! */ /* We got it! */

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* sched/semaphore/sem_trywait.c * sched/semaphore/sem_trywait.c
* *
* Copyright (C) 2007-2009, 2016 Gregory Nutt. All rights reserved. * Copyright (C) 2007-2009, 2016-2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -55,7 +55,7 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: sem_trywait * Name: nxsem_trywait
* *
* Description: * Description:
* This function locks the specified semaphore only if the semaphore is * This function locks the specified semaphore only if the semaphore is
@ -66,21 +66,23 @@
* sem - the semaphore descriptor * sem - the semaphore descriptor
* *
* Return Value: * Return Value:
* 0 (OK) or -1 (ERROR) if unsuccessful. If this function returns -1 * This is an internal OS interface and should not be used by applications.
* (ERROR),then the cause of the failure will be reported in "errno" as: * It follows the NuttX internal error return policy: Zero (OK) is
* returned on success. A negated errno value is returned on failure.
* Possible returned errors:
* *
* EINVAL: Invalid attempt to get the semaphore * EINVAL - Invalid attempt to get the semaphore
* EAGAIN: The semaphore is not available. * EAGAIN - The semaphore is not available.
* *
* Assumptions: * Assumptions:
* *
****************************************************************************/ ****************************************************************************/
int sem_trywait(FAR sem_t *sem) int nxsem_trywait(FAR sem_t *sem)
{ {
FAR struct tcb_s *rtcb = this_task(); FAR struct tcb_s *rtcb = this_task();
irqstate_t flags; irqstate_t flags;
int ret = ERROR; int ret;
/* This API should not be called from interrupt handlers */ /* This API should not be called from interrupt handlers */
@ -108,7 +110,7 @@ int sem_trywait(FAR sem_t *sem)
{ {
/* Semaphore is not available */ /* Semaphore is not available */
set_errno(EAGAIN); ret = -EAGAIN;
} }
/* Interrupts may now be enabled. */ /* Interrupts may now be enabled. */
@ -117,7 +119,44 @@ int sem_trywait(FAR sem_t *sem)
} }
else else
{ {
set_errno(EINVAL); ret = -EINVAL;
}
return ret;
}
/****************************************************************************
* Name: sem_trywait
*
* Description:
* This function locks the specified semaphore only if the semaphore is
* currently not locked. Otherwise, it locks the semaphore. In either
* case, the call returns without blocking.
*
* Parameters:
* sem - the semaphore descriptor
*
* Return Value:
* Zero (OK) on success or -1 (ERROR) if unsuccessful. If this function
* returns -1(ERROR), then the cause of the failure will be reported in
* errno variable as:
*
* EINVAL - Invalid attempt to get the semaphore
* EAGAIN - The semaphore is not available.
*
****************************************************************************/
int sem_trywait(FAR sem_t *sem)
{
int ret;
/* Let nxsem_trywait do the real work */
ret = nxsem_trywait(sem);
if (ret < 0)
{
set_errno(-ret);
ret = ERROR;
} }
return ret; return ret;

View File

@ -52,6 +52,7 @@
#include <nuttx/kmalloc.h> #include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h> #include <nuttx/wqueue.h>
#include <nuttx/semaphore.h>
#include <nuttx/mm/iob.h> #include <nuttx/mm/iob.h>
@ -168,7 +169,7 @@ int mac802154_txdesc_alloc(FAR struct ieee802154_privmac_s *priv,
* The MAC is already locked, so there shouldn't be any other conflicting calls * The MAC is already locked, so there shouldn't be any other conflicting calls
*/ */
ret = sem_trywait(&priv->txdesc_sem); ret = nxsem_trywait(&priv->txdesc_sem);
if (ret == OK) if (ret == OK)
{ {
*txdesc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->txdesc_queue); *txdesc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->txdesc_queue);

View File

@ -50,6 +50,8 @@
#include <debug.h> #include <debug.h>
#include <string.h> #include <string.h>
#include <nuttx/semaphore.h>
#include "mac802154.h" #include "mac802154.h"
#include "mac802154_internal.h" #include "mac802154_internal.h"
@ -158,7 +160,7 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv,
* The MAC is already locked, so there shouldn't be any other conflicting calls * The MAC is already locked, so there shouldn't be any other conflicting calls
*/ */
ret = sem_trywait(&priv->notif_sem); ret = nxsem_trywait(&priv->notif_sem);
if (ret == OK) if (ret == OK)
{ {