sem_tickwait(): Add a new, non-standard function to perform timed semaphore waits. It is functionally equialent to the standard sem_timedwait(), but more efficient for use in higher performance device drivers. Requested by Max Neklyudov

This commit is contained in:
Gregory Nutt 2015-08-01 07:30:23 -06:00
parent 5772813d29
commit 2c66e0eb2a
7 changed files with 50 additions and 144 deletions

View File

@ -10776,4 +10776,7 @@
Based comments from Anton D. Kachalov (2015-07-29).
* STM32 F4: Add DMA support to the ADC driver for STM32 F4. From
Max Kriegler (2015-07-30).
* sem_tickwait(): Added this furnction for internaluse within the
OS. It is a non-standard but more efficient version of sem_timedwait()
for use in higher performance device drviers (2015-08-01).

View File

@ -1,7 +1,7 @@
/****************************************************************************
* include/nuttx/semaphore.h
*
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -51,7 +51,7 @@
****************************************************************************/
/****************************************************************************
* Public Data
* Public Type Definitions
****************************************************************************/
#ifdef CONFIG_FS_NAMED_SEMAPHORES
@ -64,7 +64,6 @@ struct nsem_inode_s
FAR struct inode *ns_inode; /* Containing inode */
sem_t ns_sem; /* The semaphore */
};
#endif
@ -86,6 +85,26 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: sem_tickwait
*
* Description:
* This function is a lighter weight version of sem_timedwait(). It is
* non-standard and intended only for use within the RTOS.
*
* Parameters:
* sem - Semaphore object
* ticks - Ticks to wait until the semaphore is posted. If ticks is
* zero, then this function is equivalent to sem_trywait().
*
* Return Value:
* Zero (OK) is returned on success. A negated errno value is returned on
* failure. -ETIMEDOUT is returned on the timeout condition.
*
****************************************************************************/
int sem_tickwait(FAR sem_t *sem, uint32_t ticks);
#undef EXTERN
#ifdef __cplusplus
}

View File

@ -1,7 +1,7 @@
############################################################################
# sched/semaphore/Make.defs
#
# Copyright (C) 2014 Gregory Nutt. All rights reserved.
# Copyright (C) 2014-2015 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -33,8 +33,9 @@
#
############################################################################
CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_timedwait.c
CSRCS += sem_post.c sem_recover.c sem_waitirq.c
CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_tickwait.c
CSRCS += sem_timedwait.c sem_timeout.c sem_post.c sem_recover.c
CSRCS += sem_waitirq.c
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
CSRCS += sem_initialize.c sem_holder.c

View File

@ -45,26 +45,6 @@
#ifdef CONFIG_PRIORITY_INHERITANCE
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Global Variables
****************************************************************************/
/****************************************************************************
* Private Variables
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
@ -83,6 +63,7 @@
* None
*
* Assumptions:
* Called once during OS startup initialization
*
****************************************************************************/

View File

@ -53,75 +53,6 @@
#include "clock/clock.h"
#include "semaphore/semaphore.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Global Variables
****************************************************************************/
/****************************************************************************
* Private Variables
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: sem_timeout
*
* Description:
* This function is called if the timeout elapses before the message queue
* becomes non-empty.
*
* Parameters:
* argc - the number of arguments (should be 1)
* pid - the task ID of the task to wakeup
*
* Return Value:
* None
*
* Assumptions:
*
****************************************************************************/
static void sem_timeout(int argc, wdparm_t pid)
{
FAR struct tcb_s *wtcb;
irqstate_t flags;
/* Disable interrupts to avoid race conditions */
flags = irqsave();
/* Get the TCB associated with this pid. It is possible that
* task may no longer be active when this watchdog goes off.
*/
wtcb = sched_gettcb((pid_t)pid);
/* It is also possible that an interrupt/context switch beat us to the
* punch and already changed the task's state.
*/
if (wtcb && wtcb->task_state == TSTATE_WAIT_SEM)
{
/* Cancel the semaphore wait */
sem_waitirq(wtcb, ETIMEDOUT);
}
/* Interrupts may now be enabled. */
irqrestore(flags);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -147,9 +78,8 @@ static void sem_timeout(int argc, wdparm_t pid)
* abstime - The absolute time to wait until a timeout is declared.
*
* Return Value:
* One success, the length of the selected message in bytes is
* returned. On failure, -1 (ERROR) is returned and the errno
* is set appropriately:
* Zero (OK) is returned on success. On failure, -1 (ERROR) is returned
* and the errno is set appropriately:
*
* EINVAL The sem argument does not refer to a valid semaphore. Or the
* thread would have blocked, and the abstime parameter specified
@ -213,10 +143,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
{
/* We got it! */
irqrestore(flags);
wd_delete(rtcb->waitdog);
rtcb->waitdog = NULL;
return OK;
goto success_with_irqdisabled;
}
/* We will have to wait for the semaphore. Make sure that we were provided
@ -226,7 +153,7 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
{
errcode = EINVAL;
goto errout_disabled;
goto errout_with_irqdisabled;
}
/* Convert the timespec to clock ticks. We must have interrupts
@ -240,20 +167,20 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
if (errcode == OK && ticks <= 0)
{
errcode = ETIMEDOUT;
goto errout_disabled;
goto errout_with_irqdisabled;
}
/* Handle any time-related errors */
if (errcode != OK)
{
goto errout_disabled;
goto errout_with_irqdisabled;
}
/* Start the watchdog */
errcode = OK;
wd_start(rtcb->waitdog, ticks, (wdentry_t)sem_timeout, 1, getpid());
(void)wd_start(rtcb->waitdog, ticks, (wdentry_t)sem_timeout, 1, getpid());
/* Now perform the blocking wait */
@ -271,28 +198,17 @@ int sem_timedwait(FAR sem_t *sem, FAR const struct timespec *abstime)
/* We can now restore interrupts and delete the watchdog */
/* Success exits */
success_with_irqdisabled:
irqrestore(flags);
wd_delete(rtcb->waitdog);
rtcb->waitdog = NULL;
return OK;
/* We are either returning success or an error detected by sem_wait()
* or the timeout detected by sem_timeout(). The 'errno' value has
* been set appropriately by sem_wait() or sem_timeout() in those
* cases.
*/
/* Error exits */
if (ret < 0)
{
/* On failure, restore the errno value returned by sem_wait */
set_errno(errcode);
}
return ret;
/* Error exits */
errout_disabled:
errout_with_irqdisabled:
irqrestore(flags);
wd_delete(rtcb->waitdog);
rtcb->waitdog = NULL;

View File

@ -45,26 +45,6 @@
#include "semaphore/semaphore.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Type Declarations
****************************************************************************/
/****************************************************************************
* Global Variables
****************************************************************************/
/****************************************************************************
* Private Variables
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/

View File

@ -1,7 +1,7 @@
/****************************************************************************
* sched/semaphore/semaphore.h
*
* Copyright (C) 2007, 2009-2014 Gregory Nutt. All rights reserved.
* Copyright (C) 2007, 2009-2015 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -81,8 +81,14 @@ void sem_initialize(void);
# define sem_initialize()
#endif
/* Wake up a thread that is waiting on semaphore */
void sem_waitirq(FAR struct tcb_s *wtcb, int errcode);
/* Handle semaphore timer expiration */
void sem_timeout(int argc, wdparm_t pid);
/* Recover semaphore resources with a task or thread is destroyed */
void sem_recover(FAR struct tcb_s *tcb);