Fix for sem_timedwait.c
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3803 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
b896f16bcf
commit
fe4c8b72b0
@ -117,10 +117,10 @@ PTHREAD_SRCS += pthread_condtimedwait.c pthread_kill.c pthread_sigmask.c
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
SEM_SRCS = sem_initialize.c sem_destroy.c sem_open.c sem_close.c sem_unlink.c \
|
SEM_SRCS = sem_initialize.c sem_destroy.c sem_open.c sem_close.c sem_unlink.c \
|
||||||
sem_wait.c sem_trywait.c sem_post.c sem_findnamed.c
|
sem_wait.c sem_trywait.c sem_timedwait.c sem_post.c sem_findnamed.c
|
||||||
|
|
||||||
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
ifneq ($(CONFIG_DISABLE_SIGNALS),y)
|
||||||
SEM_SRCS += sem_waitirq.c sem_timedwait.c
|
SEM_SRCS += sem_waitirq.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
|
ifeq ($(CONFIG_PRIORITY_INHERITANCE),y)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/sem_internal.h
|
* sched/sem_internal.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009-2010 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009-2011 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -90,7 +90,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXTERN void weak_function sem_initialize(void);
|
EXTERN void weak_function sem_initialize(void);
|
||||||
EXTERN void sem_waitirq(FAR _TCB *wtcb);
|
EXTERN void sem_waitirq(FAR _TCB *wtcb, int errcode);
|
||||||
EXTERN FAR nsem_t *sem_findnamed(const char *name);
|
EXTERN FAR nsem_t *sem_findnamed(const char *name);
|
||||||
|
|
||||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/sem_timedwait.c
|
* sched/sem_timedwait.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -51,6 +51,7 @@
|
|||||||
|
|
||||||
#include "os_internal.h"
|
#include "os_internal.h"
|
||||||
#include "clock_internal.h"
|
#include "clock_internal.h"
|
||||||
|
#include "sem_internal.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Pre-processor Definitions
|
* Pre-processor Definitions
|
||||||
@ -111,13 +112,9 @@ static void sem_timeout(int argc, uint32_t pid)
|
|||||||
|
|
||||||
if (wtcb && wtcb->task_state == TSTATE_WAIT_SEM)
|
if (wtcb && wtcb->task_state == TSTATE_WAIT_SEM)
|
||||||
{
|
{
|
||||||
/* Mark the errno value for the thread. */
|
/* Cancel the semaphore wait */
|
||||||
|
|
||||||
wtcb->pterrno = ETIMEDOUT;
|
sem_waitirq(wtcb, ETIMEDOUT);
|
||||||
|
|
||||||
/* Restart the task. */
|
|
||||||
|
|
||||||
up_unblock_task(wtcb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Interrupts may now be enabled. */
|
/* Interrupts may now be enabled. */
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/sem_wait.c
|
* sched/sem_wait.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -171,16 +171,16 @@ int sem_wait(FAR sem_t *sem)
|
|||||||
#endif
|
#endif
|
||||||
/* Add the TCB to the prioritized semaphore wait queue */
|
/* Add the TCB to the prioritized semaphore wait queue */
|
||||||
|
|
||||||
errno = 0;
|
errno = OK;
|
||||||
up_block_task(rtcb, TSTATE_WAIT_SEM);
|
up_block_task(rtcb, TSTATE_WAIT_SEM);
|
||||||
|
|
||||||
/* When we resume at this point, either (1) the semaphore has been
|
/* When we resume at this point, either (1) the semaphore has been
|
||||||
* assigned to this thread of execution, or (2) the semaphore wait
|
* assigned to this thread of execution, or (2) the semaphore wait
|
||||||
* has been interrupted by a signal. We can detect the latter case
|
* has been interrupted by a signal or a timeout. We can detect these
|
||||||
* be examining the errno value.
|
* latter cases be examining the errno value.
|
||||||
*
|
*
|
||||||
* In the event that the semaphore wait was interrupt was interrupted
|
* In the event that the semaphore wait was interrupted by a signal or
|
||||||
* by a signal, certain semaphore clean-up operations have already been
|
* a timeout, certain semaphore clean-up operations have already been
|
||||||
* performed (see sem_waitirq.c). Specifically:
|
* performed (see sem_waitirq.c). Specifically:
|
||||||
*
|
*
|
||||||
* - sem_canceled() was called to restore the priority of all threads
|
* - sem_canceled() was called to restore the priority of all threads
|
||||||
@ -194,9 +194,9 @@ int sem_wait(FAR sem_t *sem)
|
|||||||
* race conditions.
|
* race conditions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (errno != EINTR)
|
if (errno != EINTR && errno != ETIMEDOUT)
|
||||||
{
|
{
|
||||||
/* We hold the semaphore */
|
/* Not awakened by a signal or a timeout... We hold the semaphore */
|
||||||
|
|
||||||
sem_addholder(sem);
|
sem_addholder(sem);
|
||||||
ret = OK;
|
ret = OK;
|
||||||
|
@ -73,15 +73,16 @@
|
|||||||
* Function: sem_waitirq
|
* Function: sem_waitirq
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function is called when a signal is received by a
|
* This function is called when a signal is received by a task that is
|
||||||
* task that is waiting on a semaphore. According to the
|
* waiting on a semaphore. According to the POSIX spec, "...the calling
|
||||||
* POSIX spec, "...the calling thread shall not return
|
* thread shall not return from the call to [sem_wait] until it either
|
||||||
* from the call to [sem_wait] until it either locks the
|
* locks the semaphore or the call is interrupted by a signal."
|
||||||
* semaphore or the call is interrupted by a signal."
|
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* wtcb - A pointer to the TCB of the task that is waiting
|
* wtcb - A pointer to the TCB of the task that is waiting on a
|
||||||
* on a semphare, but has received a signal instead.
|
* semphaphore, but has received a signal or timeout instead.
|
||||||
|
* errcode - EINTR if the semaphore wait was awakened by a signal;
|
||||||
|
* ETIMEDOUT if awakened by a timeout
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* None
|
* None
|
||||||
@ -90,7 +91,7 @@
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void sem_waitirq(FAR _TCB *wtcb)
|
void sem_waitirq(FAR _TCB *wtcb, int errcode)
|
||||||
{
|
{
|
||||||
irqstate_t saved_state;
|
irqstate_t saved_state;
|
||||||
|
|
||||||
@ -101,8 +102,8 @@ void sem_waitirq(FAR _TCB *wtcb)
|
|||||||
|
|
||||||
saved_state = irqsave();
|
saved_state = irqsave();
|
||||||
|
|
||||||
/* It is possible that an interrupt/context switch beat us to the
|
/* It is possible that an interrupt/context switch beat us to the punch
|
||||||
* punch and already changed the task's state.
|
* and already changed the task's state.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (wtcb->task_state == TSTATE_WAIT_SEM)
|
if (wtcb->task_state == TSTATE_WAIT_SEM)
|
||||||
@ -116,10 +117,10 @@ void sem_waitirq(FAR _TCB *wtcb)
|
|||||||
|
|
||||||
sem_canceled(wtcb, sem);
|
sem_canceled(wtcb, sem);
|
||||||
|
|
||||||
/* And increment the count on the semaphore. This releases the
|
/* And increment the count on the semaphore. This releases the count
|
||||||
* count that was taken by sem_post(). This count decremented
|
* that was taken by sem_post(). This count decremented the semaphore
|
||||||
* the semaphore count to negative and caused the thread to be
|
* count to negative and caused the thread to be blocked in the first
|
||||||
* blocked in the first place.
|
* place.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sem->semcount++;
|
sem->semcount++;
|
||||||
@ -130,7 +131,7 @@ void sem_waitirq(FAR _TCB *wtcb)
|
|||||||
|
|
||||||
/* Mark the errno value for the thread. */
|
/* Mark the errno value for the thread. */
|
||||||
|
|
||||||
wtcb->pterrno = EINTR;
|
wtcb->pterrno = errcode;
|
||||||
|
|
||||||
/* Restart the task. */
|
/* Restart the task. */
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* sched/sig_received.c
|
* sched/sig_received.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -43,7 +43,9 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
#include "os_internal.h"
|
#include "os_internal.h"
|
||||||
@ -377,7 +379,7 @@ int sig_received(FAR _TCB *stcb, siginfo_t *info)
|
|||||||
|
|
||||||
if (stcb->task_state == TSTATE_WAIT_SEM)
|
if (stcb->task_state == TSTATE_WAIT_SEM)
|
||||||
{
|
{
|
||||||
sem_waitirq(stcb);
|
sem_waitirq(stcb, EINTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the task is blocked waiting on a message queue, then that
|
/* If the task is blocked waiting on a message queue, then that
|
||||||
|
Loading…
x
Reference in New Issue
Block a user