summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src/condtimedwait.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/posix/src/condtimedwait.c')
-rw-r--r--cpukit/posix/src/condtimedwait.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/cpukit/posix/src/condtimedwait.c b/cpukit/posix/src/condtimedwait.c
index 32ce1d4a05..204dae858c 100644
--- a/cpukit/posix/src/condtimedwait.c
+++ b/cpukit/posix/src/condtimedwait.c
@@ -28,34 +28,34 @@ int pthread_cond_timedwait(
const struct timespec *abstime
)
{
- Watchdog_Interval timeout;
- struct timespec current_time;
- struct timespec difference;
- boolean already_timedout = FALSE;
-
- if ( !abstime )
- return EINVAL;
+ Watchdog_Interval ticks;
+ boolean already_timedout;
/*
- * The abstime is a walltime. We turn it into an interval.
+ * POSIX requires that blocking calls with timeouts that take
+ * an absolute timeout must ignore issues with the absolute
+ * time provided if the operation would otherwise succeed.
+ * So we check the abstime provided, and hold on to whether it
+ * is valid or not. If it isn't correct and in the future,
+ * then we do a polling operation and convert the UNSATISFIED
+ * status into the appropriate error.
*/
-
- (void) clock_gettime( CLOCK_REALTIME, &current_time );
-
- /* XXX probably some error checking should go here */
-
- _POSIX_Timespec_subtract( &current_time, abstime, &difference );
-
- if ( ( difference.tv_sec < 0 ) || ( ( difference.tv_sec == 0 ) &&
- ( difference.tv_nsec < 0 ) ) )
- already_timedout = TRUE;
-
- timeout = _POSIX_Timespec_to_interval( &difference );
+ switch ( _POSIX_Absolute_timeout_to_ticks(abstime, &ticks) ) {
+ case POSIX_ABSOLUTE_TIMEOUT_INVALID:
+ return EINVAL;
+ case POSIX_ABSOLUTE_TIMEOUT_IS_IN_PAST:
+ case POSIX_ABSOLUTE_TIMEOUT_IS_NOW:
+ already_timedout = TRUE;
+ break;
+ case POSIX_ABSOLUTE_TIMEOUT_IS_IN_FUTURE:
+ already_timedout = FALSE;
+ break;
+ }
return _POSIX_Condition_variables_Wait_support(
cond,
mutex,
- timeout,
+ ticks,
already_timedout
);
}