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:
patacongo 2011-07-20 13:19:07 +00:00
parent b896f16bcf
commit fe4c8b72b0
6 changed files with 37 additions and 37 deletions

View File

@ -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)

View File

@ -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

View File

@ -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. */

View File

@ -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;

View File

@ -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. */

View File

@ -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