diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-10-29 20:29:05 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-11-02 14:08:32 +0100 |
commit | 3e81d52e27ea030fc93580c610c40616ab2b0559 (patch) | |
tree | 5fe2bbc0217d90328a9c6d8ad43fb9bb3cbb0ddf /cpukit | |
parent | tests: Use printf() instead of fprintf() (diff) | |
download | rtems-3e81d52e27ea030fc93580c610c40616ab2b0559.tar.bz2 |
posix: Use far future for very long timeouts
Close #3205.
Diffstat (limited to 'cpukit')
-rw-r--r-- | cpukit/posix/src/nanosleep.c | 14 | ||||
-rw-r--r-- | cpukit/posix/src/sigtimedwait.c | 16 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/watchdogimpl.h | 30 |
3 files changed, 38 insertions, 22 deletions
diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c index f65c91bc17..5bd1b00aa9 100644 --- a/cpukit/posix/src/nanosleep.c +++ b/cpukit/posix/src/nanosleep.c @@ -63,7 +63,7 @@ int clock_nanosleep( ) { Thread_queue_Context queue_context; - struct timespec spare_end; + struct timespec uptime; const struct timespec *end; Thread_Control *executing; int eno; @@ -93,16 +93,8 @@ int clock_nanosleep( ); } } else { - if ( !_Watchdog_Is_valid_interval_timespec( rqtp ) ) { - return EINVAL; - } - - _TOD_Get_zero_based_uptime_as_timespec( &spare_end ); - - /* In case this overflows, then the enqueue callout will reject it */ - _Timespec_Add_to( &spare_end, rqtp ); - - end = &spare_end; + _TOD_Get_zero_based_uptime_as_timespec( &uptime ); + end = _Watchdog_Future_timespec( &uptime, rqtp ); _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec( &queue_context, end diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c index a0e18adef0..72f4919be9 100644 --- a/cpukit/posix/src/sigtimedwait.c +++ b/cpukit/posix/src/sigtimedwait.c @@ -76,6 +76,7 @@ int sigtimedwait( siginfo_t signal_information; siginfo_t *the_info; int signo; + struct timespec uptime; Thread_queue_Context queue_context; int error; @@ -92,20 +93,13 @@ int sigtimedwait( */ if ( timeout != NULL ) { - struct timespec end; - - if ( !_Watchdog_Is_valid_interval_timespec( timeout ) ) { - return EINVAL; - } - - _TOD_Get_zero_based_uptime_as_timespec( &end ); - - /* In case this overflows, then the enqueue callout will reject it */ - _Timespec_Add_to( &end, timeout ); + const struct timespec *end; + _TOD_Get_zero_based_uptime_as_timespec( &uptime ); + end = _Watchdog_Future_timespec( &uptime, timeout ); _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec( &queue_context, - &end + end ); } else { _Thread_queue_Context_set_enqueue_do_nothing_extra( &queue_context ); diff --git a/cpukit/score/include/rtems/score/watchdogimpl.h b/cpukit/score/include/rtems/score/watchdogimpl.h index 7866c0ce44..f219a70768 100644 --- a/cpukit/score/include/rtems/score/watchdogimpl.h +++ b/cpukit/score/include/rtems/score/watchdogimpl.h @@ -324,6 +324,36 @@ RTEMS_INLINE_ROUTINE bool _Watchdog_Is_valid_interval_timespec( return _Watchdog_Is_valid_timespec( ts ) && ts->tv_sec >= 0; } +RTEMS_INLINE_ROUTINE const struct timespec * _Watchdog_Future_timespec( + struct timespec *now, + const struct timespec *delta +) +{ + uint64_t sec; + + if ( !_Watchdog_Is_valid_interval_timespec( delta ) ) { + return NULL; + } + + sec = (uint64_t) now->tv_sec; + sec += (uint64_t) delta->tv_sec; + now->tv_nsec += delta->tv_nsec; + + /* We have 2 * (2**63 - 1) + 1 == UINT64_MAX */ + if ( now->tv_nsec >= WATCHDOG_NANOSECONDS_PER_SECOND ) { + now->tv_nsec -= WATCHDOG_NANOSECONDS_PER_SECOND; + ++sec; + } + + if ( sec <= INT64_MAX ) { + now->tv_sec = sec; + } else { + now->tv_sec = INT64_MAX; + } + + return now; +} + RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_monotonic_timespec( const struct timespec *ts ) |