forked from Imagelibrary/rtems
2006-10-30 Joel Sherrill <joel@OARcorp.com>
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.
This commit is contained in:
@@ -1,3 +1,15 @@
|
||||
2006-10-30 Joel Sherrill <joel@OARcorp.com>
|
||||
|
||||
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 <jennifer@oarcorp.com>
|
||||
|
||||
* libcsupport/src/termios.c: Change attribute of semaphore. It was
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 );
|
||||
|
||||
ticks = _POSIX_Timespec_to_interval( &difference );
|
||||
|
||||
return _POSIX_Semaphore_Wait_support( sem, TRUE, ticks );
|
||||
return _POSIX_Semaphore_Wait_support( sem, blocking, ticks );
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user