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 Nekyudov
This commit is contained in:
parent
5772813d29
commit
e23933a004
@ -10776,4 +10776,7 @@
|
|||||||
Based comments from Anton D. Kachalov (2015-07-29).
|
Based comments from Anton D. Kachalov (2015-07-29).
|
||||||
* STM32 F4: Add DMA support to the ADC driver for STM32 F4. From
|
* STM32 F4: Add DMA support to the ADC driver for STM32 F4. From
|
||||||
Max Kriegler (2015-07-30).
|
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
|
* 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>
|
* 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
|
||||||
@ -51,7 +51,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Data
|
* Public Type Definitions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_FS_NAMED_SEMAPHORES
|
#ifdef CONFIG_FS_NAMED_SEMAPHORES
|
||||||
@ -64,7 +64,6 @@ struct nsem_inode_s
|
|||||||
|
|
||||||
FAR struct inode *ns_inode; /* Containing inode */
|
FAR struct inode *ns_inode; /* Containing inode */
|
||||||
sem_t ns_sem; /* The semaphore */
|
sem_t ns_sem; /* The semaphore */
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -86,6 +85,26 @@ extern "C"
|
|||||||
* Public Function Prototypes
|
* 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
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
############################################################################
|
############################################################################
|
||||||
# sched/semaphore/Make.defs
|
# 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>
|
# 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
|
||||||
@ -33,8 +33,9 @@
|
|||||||
#
|
#
|
||||||
############################################################################
|
############################################################################
|
||||||
|
|
||||||
CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_timedwait.c
|
CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_tickwait.c
|
||||||
CSRCS += sem_post.c sem_recover.c sem_waitirq.c
|
CSRCS += sem_timedwait.c sem_timeout.c sem_post.c sem_recover.c
|
||||||
|
CSRCS += sem_waitirq.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
|
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
|
||||||
CSRCS += sem_initialize.c sem_holder.c
|
CSRCS += sem_initialize.c sem_holder.c
|
||||||
|
@ -45,26 +45,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Type Declarations
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Global Variables
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Variables
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -83,6 +63,7 @@
|
|||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
* Assumptions:
|
||||||
|
* Called once during OS startup initialization
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
@ -53,75 +53,6 @@
|
|||||||
#include "clock/clock.h"
|
#include "clock/clock.h"
|
||||||
#include "semaphore/semaphore.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
|
* 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.
|
* abstime - The absolute time to wait until a timeout is declared.
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* One success, the length of the selected message in bytes is
|
* Zero (OK) is returned on success. On failure, -1 (ERROR) is returned
|
||||||
* returned. On failure, -1 (ERROR) is returned and the errno
|
* and the errno is set appropriately:
|
||||||
* is set appropriately:
|
|
||||||
*
|
*
|
||||||
* EINVAL The sem argument does not refer to a valid semaphore. Or the
|
* EINVAL The sem argument does not refer to a valid semaphore. Or the
|
||||||
* thread would have blocked, and the abstime parameter specified
|
* 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! */
|
/* We got it! */
|
||||||
|
|
||||||
irqrestore(flags);
|
goto success_with_irqdisabled;
|
||||||
wd_delete(rtcb->waitdog);
|
|
||||||
rtcb->waitdog = NULL;
|
|
||||||
return OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We will have to wait for the semaphore. Make sure that we were provided
|
/* 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)
|
if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
|
||||||
{
|
{
|
||||||
errcode = EINVAL;
|
errcode = EINVAL;
|
||||||
goto errout_disabled;
|
goto errout_with_irqdisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the timespec to clock ticks. We must have interrupts
|
/* 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)
|
if (errcode == OK && ticks <= 0)
|
||||||
{
|
{
|
||||||
errcode = ETIMEDOUT;
|
errcode = ETIMEDOUT;
|
||||||
goto errout_disabled;
|
goto errout_with_irqdisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle any time-related errors */
|
/* Handle any time-related errors */
|
||||||
|
|
||||||
if (errcode != OK)
|
if (errcode != OK)
|
||||||
{
|
{
|
||||||
goto errout_disabled;
|
goto errout_with_irqdisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the watchdog */
|
/* Start the watchdog */
|
||||||
|
|
||||||
errcode = OK;
|
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 */
|
/* 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 */
|
/* We can now restore interrupts and delete the watchdog */
|
||||||
|
|
||||||
|
/* Success exits */
|
||||||
|
|
||||||
|
success_with_irqdisabled:
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
wd_delete(rtcb->waitdog);
|
wd_delete(rtcb->waitdog);
|
||||||
rtcb->waitdog = NULL;
|
rtcb->waitdog = NULL;
|
||||||
|
return OK;
|
||||||
|
|
||||||
/* We are either returning success or an error detected by sem_wait()
|
/* Error exits */
|
||||||
* or the timeout detected by sem_timeout(). The 'errno' value has
|
|
||||||
* been set appropriately by sem_wait() or sem_timeout() in those
|
|
||||||
* cases.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ret < 0)
|
errout_with_irqdisabled:
|
||||||
{
|
|
||||||
/* On failure, restore the errno value returned by sem_wait */
|
|
||||||
|
|
||||||
set_errno(errcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Error exits */
|
|
||||||
|
|
||||||
errout_disabled:
|
|
||||||
irqrestore(flags);
|
irqrestore(flags);
|
||||||
wd_delete(rtcb->waitdog);
|
wd_delete(rtcb->waitdog);
|
||||||
rtcb->waitdog = NULL;
|
rtcb->waitdog = NULL;
|
||||||
|
@ -45,26 +45,6 @@
|
|||||||
|
|
||||||
#include "semaphore/semaphore.h"
|
#include "semaphore/semaphore.h"
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Pre-processor Definitions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Type Declarations
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Global Variables
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Variables
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Private Functions
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/semaphore/semaphore.h
|
* 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>
|
* 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
|
||||||
@ -81,8 +81,14 @@ void sem_initialize(void);
|
|||||||
# define sem_initialize()
|
# define sem_initialize()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Wake up a thread that is waiting on semaphore */
|
||||||
|
|
||||||
void sem_waitirq(FAR struct tcb_s *wtcb, int errcode);
|
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 */
|
/* Recover semaphore resources with a task or thread is destroyed */
|
||||||
|
|
||||||
void sem_recover(FAR struct tcb_s *tcb);
|
void sem_recover(FAR struct tcb_s *tcb);
|
||||||
|
Loading…
Reference in New Issue
Block a user