summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2006-10-30 22:21:23 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2006-10-30 22:21:23 +0000
commit0c2ec7f52c496e436f09d44dcb880bf4ea16ba86 (patch)
treea9b300a256bb640e1abfdc6dbbb6eac0a49c6a96
parent2006-10-30 Joel Sherrill <joel@OARcorp.com> (diff)
downloadrtems-0c2ec7f52c496e436f09d44dcb880bf4ea16ba86.tar.bz2
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.
-rw-r--r--cpukit/ChangeLog12
-rw-r--r--cpukit/itron/inline/rtems/itron/semaphore.inl2
-rw-r--r--cpukit/itron/src/twai_sem.c27
-rw-r--r--cpukit/posix/include/rtems/posix/semaphore.h6
-rw-r--r--cpukit/posix/inline/rtems/posix/semaphore.inl2
-rw-r--r--cpukit/posix/src/semaphorewaitsupp.c13
-rw-r--r--cpukit/posix/src/semtimedwait.c49
-rw-r--r--cpukit/posix/src/semwait.c6
-rw-r--r--cpukit/rtems/src/semobtain.c17
-rw-r--r--cpukit/rtems/src/semtranslatereturncode.c26
-rw-r--r--cpukit/score/include/rtems/score/coresem.h38
-rw-r--r--cpukit/score/src/coresemseize.c34
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 <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
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, &current_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( &current_time, abstime, &difference );
+ blocking = CORE_SEMAPHORE_BAD_TIMEOUT_VALUE;
+ else {
+ (void) clock_gettime( CLOCK_REALTIME, &current_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( &current_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;
/**
@@ -116,6 +123,25 @@ typedef struct {
} 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.
*
* @param[in] the_semaphore is the semaphore to initialize
@@ -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 );
}