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:
parent
5772813d29
commit
2c66e0eb2a
|
@ -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).
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -45,26 +45,6 @@
|
|||
|
||||
#include "semaphore/semaphore.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Declarations
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue