From 0c2ec7f52c496e436f09d44dcb880bf4ea16ba86 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Mon, 30 Oct 2006 22:21:23 +0000 Subject: 2006-10-30 Joel Sherrill PR 841/rtems * itron/inline/rtems/itron/semaphore.inl, itron/src/twai_sem.c, posix/include/rtems/posix/semaphore.h, posix/inline/rtems/posix/semaphore.inl, posix/src/semaphorewaitsupp.c, posix/src/semtimedwait.c, posix/src/semwait.c, rtems/src/semobtain.c, rtems/src/semtranslatereturncode.c, score/include/rtems/score/coresem.h, score/src/coresemseize.c: Make sem_timedwait more conformant to Open Group specification. --- cpukit/ChangeLog | 12 +++++++ cpukit/itron/inline/rtems/itron/semaphore.inl | 2 ++ cpukit/itron/src/twai_sem.c | 27 ++++++++------- cpukit/posix/include/rtems/posix/semaphore.h | 6 ++-- cpukit/posix/inline/rtems/posix/semaphore.inl | 2 +- cpukit/posix/src/semaphorewaitsupp.c | 13 ++++--- cpukit/posix/src/semtimedwait.c | 49 ++++++++++++++------------- cpukit/posix/src/semwait.c | 6 +++- cpukit/rtems/src/semobtain.c | 17 ++++------ cpukit/rtems/src/semtranslatereturncode.c | 26 ++++++-------- cpukit/score/include/rtems/score/coresem.h | 38 +++++++++++++++++---- cpukit/score/src/coresemseize.c | 34 +++++++++++-------- 12 files changed, 140 insertions(+), 92 deletions(-) diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index efce3d7e8f..2bd8ef4355 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,15 @@ +2006-10-30 Joel Sherrill + + PR 841/rtems + * itron/inline/rtems/itron/semaphore.inl, itron/src/twai_sem.c, + posix/include/rtems/posix/semaphore.h, + posix/inline/rtems/posix/semaphore.inl, + posix/src/semaphorewaitsupp.c, posix/src/semtimedwait.c, + posix/src/semwait.c, rtems/src/semobtain.c, + rtems/src/semtranslatereturncode.c, + score/include/rtems/score/coresem.h, score/src/coresemseize.c: Make + sem_timedwait more conformant to Open Group specification. + 2006-10-25 Jennifer Averett * libcsupport/src/termios.c: Change attribute of semaphore. It was diff --git a/cpukit/itron/inline/rtems/itron/semaphore.inl b/cpukit/itron/inline/rtems/itron/semaphore.inl index c57347f319..1822fb8884 100644 --- a/cpukit/itron/inline/rtems/itron/semaphore.inl +++ b/cpukit/itron/inline/rtems/itron/semaphore.inl @@ -172,6 +172,8 @@ RTEMS_INLINE_ROUTINE ER _ITRON_Semaphore_Translate_core_semaphore_return_code ( return E_TMOUT; case CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED: return E_QOVR; + case CORE_SEMAPHORE_BAD_TIMEOUT_VALUE: + return E_PAR; case THREAD_STATUS_PROXY_BLOCKING: return THREAD_STATUS_PROXY_BLOCKING; } diff --git a/cpukit/itron/src/twai_sem.c b/cpukit/itron/src/twai_sem.c index 133d0647be..90b3121051 100644 --- a/cpukit/itron/src/twai_sem.c +++ b/cpukit/itron/src/twai_sem.c @@ -30,23 +30,23 @@ ER twai_sem( TMO tmout ) { - ITRON_Semaphore_Control *the_semaphore; - Objects_Locations location; - Watchdog_Interval interval; - boolean wait; - CORE_semaphore_Status status; + ITRON_Semaphore_Control *the_semaphore; + Objects_Locations location; + Watchdog_Interval interval; + Core_semaphore_Blocking_option blocking; interval = 0; if ( tmout == TMO_POL ) { - wait = FALSE; + blocking = CORE_SEMAPHORE_NO_WAIT; } else { - wait = TRUE; + blocking = CORE_SEMAPHORE_BLOCK_FOREVER; + if ( tmout != TMO_FEVR ) interval = TOD_MILLISECONDS_TO_TICKS(tmout); - } - if ( wait && _ITRON_Is_in_non_task_state() ) - return E_CTX; + if ( _ITRON_Is_in_non_task_state() ) + return E_CTX; + } the_semaphore = _ITRON_Semaphore_Get( semid, &location ); switch ( location ) { @@ -58,12 +58,13 @@ ER twai_sem( _CORE_semaphore_Seize( &the_semaphore->semaphore, the_semaphore->Object.id, - wait, /* wait for a timeout */ + blocking, /* wait for a timeout */ interval /* timeout value */ ); _Thread_Enable_dispatch(); - status = (CORE_semaphore_Status) _Thread_Executing->Wait.return_code; - return _ITRON_Semaphore_Translate_core_semaphore_return_code( status ); + return _ITRON_Semaphore_Translate_core_semaphore_return_code( + _Thread_Executing->Wait.return_code + ); } return E_OK; } diff --git a/cpukit/posix/include/rtems/posix/semaphore.h b/cpukit/posix/include/rtems/posix/semaphore.h index 5fd0f5f171..26e0a6b804 100644 --- a/cpukit/posix/include/rtems/posix/semaphore.h +++ b/cpukit/posix/include/rtems/posix/semaphore.h @@ -153,9 +153,9 @@ void _POSIX_Semaphore_Delete( */ int _POSIX_Semaphore_Wait_support( - sem_t *sem, - boolean blocking, - Watchdog_Interval timeout + sem_t *sem, + Core_semaphore_Blocking_option blocking, + Watchdog_Interval timeout ); /* diff --git a/cpukit/posix/inline/rtems/posix/semaphore.inl b/cpukit/posix/inline/rtems/posix/semaphore.inl index 6369d6f09c..5c96d75e02 100644 --- a/cpukit/posix/inline/rtems/posix/semaphore.inl +++ b/cpukit/posix/inline/rtems/posix/semaphore.inl @@ -64,7 +64,7 @@ RTEMS_INLINE_ROUTINE void _POSIX_Semaphore_Namespace_remove ( */ RTEMS_INLINE_ROUTINE POSIX_Semaphore_Control *_POSIX_Semaphore_Get ( - sem_t *id, + sem_t *id, Objects_Locations *location ) { diff --git a/cpukit/posix/src/semaphorewaitsupp.c b/cpukit/posix/src/semaphorewaitsupp.c index 7c76ff87bd..1c5f815b25 100644 --- a/cpukit/posix/src/semaphorewaitsupp.c +++ b/cpukit/posix/src/semaphorewaitsupp.c @@ -26,13 +26,13 @@ */ int _POSIX_Semaphore_Wait_support( - sem_t *sem, - boolean blocking, - Watchdog_Interval timeout + sem_t *sem, + Core_semaphore_Blocking_option blocking, + Watchdog_Interval timeout ) { - register POSIX_Semaphore_Control *the_semaphore; - Objects_Locations location; + POSIX_Semaphore_Control *the_semaphore; + Objects_Locations location; the_semaphore = _POSIX_Semaphore_Get( sem, &location ); switch ( location ) { @@ -65,6 +65,9 @@ int _POSIX_Semaphore_Wait_support( * count to the largest value the count can hold. */ break; + case CORE_SEMAPHORE_BAD_TIMEOUT_VALUE: + rtems_set_errno_and_return_minus_one( EINVAL ); + break; } } return 0; diff --git a/cpukit/posix/src/semtimedwait.c b/cpukit/posix/src/semtimedwait.c index 6acb704f7c..b0cb78deca 100644 --- a/cpukit/posix/src/semtimedwait.c +++ b/cpukit/posix/src/semtimedwait.c @@ -35,34 +35,37 @@ int sem_timedwait( /* * The abstime is a walltime. We turn it into an interval. */ - Watchdog_Interval ticks; - struct timespec current_time; - struct timespec difference; + Watchdog_Interval ticks = 0; + struct timespec current_time; + struct timespec difference; + Core_semaphore_Blocking_option blocking = CORE_SEMAPHORE_BLOCK_WITH_TIMEOUT; /* * Error check the absolute time to timeout */ +#if 0 if ( /* abstime->tv_sec < 0 || */ abstime->tv_nsec ) /* tv_sec is unsigned */ - return EINVAL; - + blocking = CORE_SEMAPHORE_BAD_TIMEOUT_VALUE; + else +#endif if ( abstime->tv_nsec >= TOD_NANOSECONDS_PER_SECOND ) - return EINVAL; - - (void) clock_gettime( CLOCK_REALTIME, ¤t_time ); - - /* - * Make sure the abstime is in the future - */ - if ( abstime->tv_sec < current_time.tv_sec ) - return EINVAL; - if ( (abstime->tv_sec == current_time.tv_sec) && - (abstime->tv_nsec <= current_time.tv_nsec) ) - return EINVAL; - - _POSIX_Timespec_subtract( ¤t_time, abstime, &difference ); + blocking = CORE_SEMAPHORE_BAD_TIMEOUT_VALUE; + else { + (void) clock_gettime( CLOCK_REALTIME, ¤t_time ); + /* + * Make sure the abstime is in the future + */ + if ( abstime->tv_sec < current_time.tv_sec ) + blocking = CORE_SEMAPHORE_BAD_TIMEOUT_VALUE; + else if ( (abstime->tv_sec == current_time.tv_sec) && + (abstime->tv_nsec <= current_time.tv_nsec) ) + blocking = CORE_SEMAPHORE_BAD_TIMEOUT_VALUE; + else { + _POSIX_Timespec_subtract( ¤t_time, abstime, &difference ); + ticks = _POSIX_Timespec_to_interval( &difference ); + blocking = CORE_SEMAPHORE_BLOCK_WITH_TIMEOUT; + } + } - ticks = _POSIX_Timespec_to_interval( &difference ); - - return _POSIX_Semaphore_Wait_support( sem, TRUE, ticks ); + return _POSIX_Semaphore_Wait_support( sem, blocking, ticks ); } - diff --git a/cpukit/posix/src/semwait.c b/cpukit/posix/src/semwait.c index 9ef787c727..b43a1e47b4 100644 --- a/cpukit/posix/src/semwait.c +++ b/cpukit/posix/src/semwait.c @@ -31,5 +31,9 @@ int sem_wait( sem_t *sem ) { - return _POSIX_Semaphore_Wait_support( sem, TRUE, THREAD_QUEUE_WAIT_FOREVER ); + return _POSIX_Semaphore_Wait_support( + sem, + CORE_SEMAPHORE_BLOCK_FOREVER, + THREAD_QUEUE_WAIT_FOREVER + ); } diff --git a/cpukit/rtems/src/semobtain.c b/cpukit/rtems/src/semobtain.c index 72ac454de5..bfa8831f6a 100644 --- a/cpukit/rtems/src/semobtain.c +++ b/cpukit/rtems/src/semobtain.c @@ -71,10 +71,9 @@ rtems_status_code rtems_semaphore_obtain( rtems_interval timeout ) { - register Semaphore_Control *the_semaphore; - Objects_Locations location; - boolean wait; - ISR_Level level; + register Semaphore_Control *the_semaphore; + Objects_Locations location; + ISR_Level level; the_semaphore = _Semaphore_Get_interrupt_disable( id, &location, &level ); switch ( location ) { @@ -92,16 +91,11 @@ rtems_status_code rtems_semaphore_obtain( return RTEMS_INVALID_ID; case OBJECTS_LOCAL: - if ( _Options_Is_no_wait( option_set ) ) - wait = FALSE; - else - wait = TRUE; - if ( !_Attributes_Is_counting_semaphore(the_semaphore->attribute_set) ) { _CORE_mutex_Seize( &the_semaphore->Core_control.mutex, id, - wait, + ((_Options_Is_no_wait( option_set )) ? FALSE : TRUE), timeout, level ); @@ -113,7 +107,8 @@ rtems_status_code rtems_semaphore_obtain( _CORE_semaphore_Seize_isr_disable( &the_semaphore->Core_control.semaphore, id, - wait, + ((_Options_Is_no_wait( option_set )) ? + CORE_SEMAPHORE_NO_WAIT : CORE_SEMAPHORE_BLOCK_FOREVER), timeout, &level ); diff --git a/cpukit/rtems/src/semtranslatereturncode.c b/cpukit/rtems/src/semtranslatereturncode.c index cc7bfffbd6..d7d2d306ac 100644 --- a/cpukit/rtems/src/semtranslatereturncode.c +++ b/cpukit/rtems/src/semtranslatereturncode.c @@ -54,7 +54,7 @@ * _Semaphore_Translate_core_mutex_return_code * * Input parameters: - * the_mutex_status - mutex status code to translate + * status - mutex status code to translate * * Output parameters: * rtems status code - translated RTEMS status code @@ -73,18 +73,16 @@ rtems_status_code _Semaphore_Translate_core_mutex_return_code_[] = { rtems_status_code _Semaphore_Translate_core_mutex_return_code ( - uint32_t the_mutex_status + uint32_t status ) { #if defined(RTEMS_MULTIPROCESSING) - if ( the_mutex_status == THREAD_STATUS_PROXY_BLOCKING ) + if ( status == THREAD_STATUS_PROXY_BLOCKING ) return RTEMS_PROXY_BLOCKING; - else #endif - if ( the_mutex_status > CORE_MUTEX_STATUS_CEILING_VIOLATED ) + if ( status > CORE_MUTEX_STATUS_CEILING_VIOLATED ) return RTEMS_INTERNAL_ERROR; - else - return _Semaphore_Translate_core_mutex_return_code_[the_mutex_status]; + return _Semaphore_Translate_core_mutex_return_code_[status]; } /*PAGE @@ -92,7 +90,7 @@ rtems_status_code _Semaphore_Translate_core_mutex_return_code ( * _Semaphore_Translate_core_semaphore_return_code * * Input parameters: - * the_semaphore_status - semaphore status code to translate + * status - semaphore status code to translate * * Output parameters: * rtems status code - translated RTEMS status code @@ -105,20 +103,18 @@ rtems_status_code _Semaphore_Translate_core_semaphore_return_code_[] = { RTEMS_OBJECT_WAS_DELETED, /* CORE_SEMAPHORE_WAS_DELETED */ RTEMS_TIMEOUT, /* CORE_SEMAPHORE_TIMEOUT */ RTEMS_INTERNAL_ERROR, /* CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED */ - + RTEMS_INTERNAL_ERROR /* CORE_SEMAPHORE_BAD_TIMEOUT_VALUE */ }; rtems_status_code _Semaphore_Translate_core_semaphore_return_code ( - uint32_t the_semaphore_status + uint32_t status ) { #if defined(RTEMS_MULTIPROCESSING) - if ( the_semaphore_status == THREAD_STATUS_PROXY_BLOCKING ) + if ( status == THREAD_STATUS_PROXY_BLOCKING ) return RTEMS_PROXY_BLOCKING; - else #endif - if ( the_semaphore_status > CORE_MUTEX_STATUS_CEILING_VIOLATED ) + if ( status > CORE_MUTEX_STATUS_CEILING_VIOLATED ) return RTEMS_INTERNAL_ERROR; - else - return _Semaphore_Translate_core_semaphore_return_code_[the_semaphore_status]; + return _Semaphore_Translate_core_semaphore_return_code_[status]; } diff --git a/cpukit/score/include/rtems/score/coresem.h b/cpukit/score/include/rtems/score/coresem.h index 7445151ecd..a146b1c1c2 100644 --- a/cpukit/score/include/rtems/score/coresem.h +++ b/cpukit/score/include/rtems/score/coresem.h @@ -82,7 +82,14 @@ typedef enum { /** This status indicates that an attempt was made to unlock the semaphore * and this would have made its count greater than that allowed. */ - CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED + CORE_SEMAPHORE_MAXIMUM_COUNT_EXCEEDED, + /** This status indicates that the semaphore was not immediately + * available and the caller passed a bad timeout value to the API + * routine. In this case, the API required that the validity check + * for the timeout occur after the check that the semaphore was immediately + * available. + */ + CORE_SEMAPHORE_BAD_TIMEOUT_VALUE } CORE_semaphore_Status; /** @@ -115,6 +122,25 @@ typedef struct { uint32_t count; } CORE_semaphore_Control; +/** + * The following enumerated type is the set of blocking options + * available to seize operation. + */ +typedef enum { + /** This value indicates that the caller does not wish to block. */ + CORE_SEMAPHORE_NO_WAIT, + /** This value indicates that the caller is willing to block forever. */ + CORE_SEMAPHORE_BLOCK_FOREVER, + /** This value indicates that the caller is blocking with a timeout. */ + CORE_SEMAPHORE_BLOCK_WITH_TIMEOUT, + /** This value indicates that the caller wanted to block but passed in + * a bad timeout value to the API. Unfortunately, this is a weird case + * where the timeout bad error is required to be generated only if + * the semaphore is not available. + */ + CORE_SEMAPHORE_BAD_TIMEOUT +} Core_semaphore_Blocking_option; + /** * This routine initializes the semaphore based on the parameters passed. * @@ -137,15 +163,15 @@ void _CORE_semaphore_Initialize( * @param[in] the_semaphore is the semaphore to seize * @param[in] id is the Id of the API level Semaphore object associated * with this instance of a SuperCore Semaphore - * @param[in] wait is TRUE if the calling thread is willing to wait + * @param[in] wait is the blocking mode * @param[in] timeout is the number of ticks the calling thread is willing * to wait if @a wait is TRUE. */ void _CORE_semaphore_Seize( - CORE_semaphore_Control *the_semaphore, - Objects_Id id, - boolean wait, - Watchdog_Interval timeout + CORE_semaphore_Control *the_semaphore, + Objects_Id id, + Core_semaphore_Blocking_option wait, + Watchdog_Interval timeout ); /** diff --git a/cpukit/score/src/coresemseize.c b/cpukit/score/src/coresemseize.c index 49c835b80b..2648a620c2 100644 --- a/cpukit/score/src/coresemseize.c +++ b/cpukit/score/src/coresemseize.c @@ -51,10 +51,10 @@ */ void _CORE_semaphore_Seize( - CORE_semaphore_Control *the_semaphore, - Objects_Id id, - boolean wait, - Watchdog_Interval timeout + CORE_semaphore_Control *the_semaphore, + Objects_Id id, + Core_semaphore_Blocking_option wait, + Watchdog_Interval timeout ) { Thread_Control *executing; @@ -69,16 +69,22 @@ void _CORE_semaphore_Seize( return; } - if ( !wait ) { - _ISR_Enable( level ); - executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT; - return; + switch ( wait ) { + case CORE_SEMAPHORE_NO_WAIT: + _ISR_Enable( level ); + executing->Wait.return_code = CORE_SEMAPHORE_STATUS_UNSATISFIED_NOWAIT; + return; + case CORE_SEMAPHORE_BAD_TIMEOUT: + executing->Wait.return_code = CORE_SEMAPHORE_BAD_TIMEOUT_VALUE; + return; + case CORE_SEMAPHORE_BLOCK_FOREVER: + case CORE_SEMAPHORE_BLOCK_WITH_TIMEOUT: + _Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue ); + executing->Wait.queue = &the_semaphore->Wait_queue; + executing->Wait.id = id; + _ISR_Enable( level ); + _Thread_queue_Enqueue( &the_semaphore->Wait_queue, timeout ); + break; } - _Thread_queue_Enter_critical_section( &the_semaphore->Wait_queue ); - executing->Wait.queue = &the_semaphore->Wait_queue; - executing->Wait.id = id; - _ISR_Enable( level ); - - _Thread_queue_Enqueue( &the_semaphore->Wait_queue, timeout ); } -- cgit v1.2.3