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 <string.h>
#include <nuttx/semaphore.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.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
*/
ret = sem_trywait(&priv->dataind_sem);
ret = nxsem_trywait(&priv->dataind_sem);
if (ret == OK)
{

View File

@ -49,6 +49,7 @@
#include "xbee_mac.h"
#include "xbee_notif.h"
#include <nuttx/semaphore.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.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
*/
ret = sem_trywait(&priv->notif_sem);
ret = nxsem_trywait(&priv->notif_sem);
if (ret == OK)
{

View File

@ -70,7 +70,7 @@
* task. Following a call to sem_open() with the semaphore name, the task
* may reference the semaphore associated with name using the address
* 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().
*
* 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.
* Possible returned errors:
*
* - EINVAL: Invalid attempt to get the semaphore
* - EINTR: The wait was interrupted by the receipt of a signal.
* EINVAL - Invalid attempt to get the semaphore
* EINTR - The wait was interrupted by the receipt of a signal.
*
****************************************************************************/
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
*

View File

@ -112,12 +112,12 @@ int nxsem_init(FAR sem_t *sem, int pshared, unsigned int value)
* Description:
* This function initializes the UNAMED semaphore sem. Following a
* 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.
*
* Only sem itself may be used for performing synchronization. The result
* 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:
* 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;
/* 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
* handler. Fortunately we know at at least one free buffer
* 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;
/* 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
* handler. Fortunately we know at at least one free buffer
* 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)
{
pid_t my_pid = getpid();
int ret;
/* 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) */
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 */

View File

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

View File

@ -46,6 +46,7 @@
#include <nuttx/irq.h>
#include <nuttx/sched.h>
#include <nuttx/semaphore.h>
#include "sched/sched.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 */
ret = sem_trywait(&mutex->sem);
if (ret < OK)
ret = nxsem_trywait(&mutex->sem);
if (ret < 0)
{
ret = get_errno();
ret = -ret;
}
else
{

View File

@ -46,6 +46,7 @@
#include <nuttx/sched.h>
#include <nuttx/cancelpt.h>
#include <nuttx/semaphore.h>
#include "sched/sched.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 */
ret = sem_trywait(&group->tg_exitsem);
ret = nxsem_trywait(&group->tg_exitsem);
group_delwaiter(group);
if (ret < 0)

View File

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

View File

@ -50,6 +50,7 @@
#include <nuttx/arch.h>
#include <nuttx/wdog.h>
#include <nuttx/cancelpt.h>
#include <nuttx/semaphore.h>
#include "sched/sched.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. */
ret = sem_trywait(sem);
ret = nxsem_trywait(sem);
if (ret == OK)
{
/* We got it! */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* 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>
*
* Redistribution and use in source and binary forms, with or without
@ -55,7 +55,7 @@
****************************************************************************/
/****************************************************************************
* Name: sem_trywait
* Name: nxsem_trywait
*
* Description:
* This function locks the specified semaphore only if the semaphore is
@ -66,21 +66,23 @@
* sem - the semaphore descriptor
*
* Return Value:
* 0 (OK) or -1 (ERROR) if unsuccessful. If this function returns -1
* (ERROR),then the cause of the failure will be reported in "errno" as:
* 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.
* EINVAL - Invalid attempt to get the semaphore
* EAGAIN - The semaphore is not available.
*
* Assumptions:
*
****************************************************************************/
int sem_trywait(FAR sem_t *sem)
int nxsem_trywait(FAR sem_t *sem)
{
FAR struct tcb_s *rtcb = this_task();
irqstate_t flags;
int ret = ERROR;
int ret;
/* This API should not be called from interrupt handlers */
@ -108,7 +110,7 @@ int sem_trywait(FAR sem_t *sem)
{
/* Semaphore is not available */
set_errno(EAGAIN);
ret = -EAGAIN;
}
/* Interrupts may now be enabled. */
@ -117,7 +119,44 @@ int sem_trywait(FAR sem_t *sem)
}
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;

View File

@ -52,6 +52,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/wqueue.h>
#include <nuttx/semaphore.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
*/
ret = sem_trywait(&priv->txdesc_sem);
ret = nxsem_trywait(&priv->txdesc_sem);
if (ret == OK)
{
*txdesc = (FAR struct ieee802154_txdesc_s *)sq_remfirst(&priv->txdesc_queue);

View File

@ -50,6 +50,8 @@
#include <debug.h>
#include <string.h>
#include <nuttx/semaphore.h>
#include "mac802154.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
*/
ret = sem_trywait(&priv->notif_sem);
ret = nxsem_trywait(&priv->notif_sem);
if (ret == OK)
{