From 9480815a222be61214b176836ef2b4ae4155ce84 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 21 Dec 2017 14:36:52 +0100 Subject: score: Introduce new monotonic clock Rename PER_CPU_WATCHDOG_MONOTONIC to PER_CPU_WATCHDOG_TICKS. Add new PER_CPU_WATCHDOG_MONOTONIC which is based on the system uptime (measured by timecounter). Close #3264. --- cpukit/include/rtems/confdefs.h | 3 - cpukit/include/rtems/score/percpu.h | 18 ++-- cpukit/include/rtems/score/threadimpl.h | 13 +-- cpukit/include/rtems/score/watchdog.h | 9 -- cpukit/include/rtems/score/watchdogimpl.h | 92 ++++----------------- cpukit/posix/src/alarm.c | 4 +- cpukit/posix/src/nanosleep.c | 6 +- cpukit/posix/src/pthread.c | 4 +- cpukit/posix/src/pthreadsetschedparam.c | 2 +- cpukit/posix/src/sigtimedwait.c | 2 +- cpukit/posix/src/timerdelete.c | 2 +- cpukit/posix/src/timersettime.c | 4 +- cpukit/posix/src/ualarm.c | 4 +- cpukit/rtems/src/ratemoncancel.c | 2 +- cpukit/rtems/src/timercreate.c | 2 +- cpukit/rtems/src/timerreset.c | 2 +- cpukit/score/src/threadqtimeout.c | 128 ++++++++++++----------------- cpukit/score/src/watchdogtick.c | 16 +++- testsuites/sptests/spintrcritical08/init.c | 4 +- testsuites/sptests/spintrcritical09/init.c | 2 +- testsuites/sptests/spwatchdog/init.c | 1 - 21 files changed, 120 insertions(+), 200 deletions(-) diff --git a/cpukit/include/rtems/confdefs.h b/cpukit/include/rtems/confdefs.h index 1c993dd099..45618b7a14 100755 --- a/cpukit/include/rtems/confdefs.h +++ b/cpukit/include/rtems/confdefs.h @@ -3112,9 +3112,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[]; const uint32_t _Watchdog_Ticks_per_second = _CONFIGURE_TICKS_PER_SECOND; - const uint64_t _Watchdog_Monotonic_max_seconds = - UINT64_MAX / _CONFIGURE_TICKS_PER_SECOND; - /** * This is the Classic API Configuration Table. */ diff --git a/cpukit/include/rtems/score/percpu.h b/cpukit/include/rtems/score/percpu.h index 00528b5ce3..7d0a6c06bf 100644 --- a/cpukit/include/rtems/score/percpu.h +++ b/cpukit/include/rtems/score/percpu.h @@ -248,14 +248,13 @@ typedef struct { */ typedef enum { /** - * @brief Index for monotonic clock per-CPU watchdog header. + * @brief Index for tick clock per-CPU watchdog header. * - * The reference time point for the monotonic clock is the system start. The + * The reference time point for the tick clock is the system start. The * clock resolution is one system clock tick. It is used for the system - * clock tick based time services and the POSIX services using - * CLOCK_MONOTONIC. + * clock tick based time services. */ - PER_CPU_WATCHDOG_MONOTONIC, + PER_CPU_WATCHDOG_TICKS, /** * @brief Index for realtime clock per-CPU watchdog header. @@ -266,6 +265,15 @@ typedef enum { */ PER_CPU_WATCHDOG_REALTIME, + /** + * @brief Index for monotonic clock per-CPU watchdog header. + * + * The reference time point for the monotonic clock is the system start. The + * clock resolution is one nanosecond. It is used for the POSIX services + * using CLOCK_MONOTONIC. + */ + PER_CPU_WATCHDOG_MONOTONIC, + /** * @brief Count of per-CPU watchdog headers. */ diff --git a/cpukit/include/rtems/score/threadimpl.h b/cpukit/include/rtems/score/threadimpl.h index b6722fae19..777158b77a 100644 --- a/cpukit/include/rtems/score/threadimpl.h +++ b/cpukit/include/rtems/score/threadimpl.h @@ -1864,7 +1864,7 @@ RTEMS_INLINE_ROUTINE void _Thread_Timer_initialize( ) { _ISR_lock_Initialize( &timer->Lock, "Thread Timer" ); - timer->header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; + timer->header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ]; _Watchdog_Preinitialize( &timer->Watchdog, cpu ); } @@ -1879,7 +1879,7 @@ RTEMS_INLINE_ROUTINE void _Thread_Add_timeout_ticks( _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context ); the_thread->Timer.header = - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ]; the_thread->Timer.Watchdog.routine = _Thread_Timeout; _Watchdog_Per_CPU_insert_ticks( &the_thread->Timer.Watchdog, cpu, ticks ); @@ -1893,14 +1893,15 @@ RTEMS_INLINE_ROUTINE void _Thread_Timer_insert_realtime( uint64_t expire ) { - ISR_lock_Context lock_context; + ISR_lock_Context lock_context; + Watchdog_Header *header; _ISR_lock_ISR_disable_and_acquire( &the_thread->Timer.Lock, &lock_context ); - the_thread->Timer.header = - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ]; + header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ]; + the_thread->Timer.header = header; the_thread->Timer.Watchdog.routine = routine; - _Watchdog_Per_CPU_insert_realtime( &the_thread->Timer.Watchdog, cpu, expire ); + _Watchdog_Per_CPU_insert( &the_thread->Timer.Watchdog, cpu, header, expire ); _ISR_lock_Release_and_ISR_enable( &the_thread->Timer.Lock, &lock_context ); } diff --git a/cpukit/include/rtems/score/watchdog.h b/cpukit/include/rtems/score/watchdog.h index dbb092bbef..71126d3508 100644 --- a/cpukit/include/rtems/score/watchdog.h +++ b/cpukit/include/rtems/score/watchdog.h @@ -147,15 +147,6 @@ extern const uint32_t _Watchdog_Nanoseconds_per_tick; */ extern const uint32_t _Watchdog_Ticks_per_second; -/** - * @brief The maximum number of seconds representable in the monotonic watchdog - * format. - * - * This constant is defined by the application configuration via - * . - */ -extern const uint64_t _Watchdog_Monotonic_max_seconds; - /**@}*/ #ifdef __cplusplus diff --git a/cpukit/include/rtems/score/watchdogimpl.h b/cpukit/include/rtems/score/watchdogimpl.h index 9701fb772f..6fe9d5acf5 100644 --- a/cpukit/include/rtems/score/watchdogimpl.h +++ b/cpukit/include/rtems/score/watchdogimpl.h @@ -303,19 +303,19 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Next_first( * @brief The bits necessary to store 1000000000 * (= WATCHDOG_NANOSECONDS_PER_SECOND) nanoseconds. * - * The expiration time is an unsigned 64-bit integer. To store absolute + * The expiration time is an unsigned 64-bit integer. To store nanoseconds * timeouts we use 30 bits (2**30 == 1073741824) for the nanoseconds and 34 * bits for the seconds since UNIX Epoch. This leads to a year 2514 problem. */ #define WATCHDOG_BITS_FOR_1E9_NANOSECONDS 30 /** - * @brief The maximum number of seconds representable in the realtime watchdog - * format. + * @brief The maximum number of seconds representable in the nanoseconds + * watchdog format. * * We have 2**34 bits for the seconds part. */ -#define WATCHDOG_REALTIME_MAX_SECONDS 0x3ffffffff +#define WATCHDOG_MAX_SECONDS 0x3ffffffff RTEMS_INLINE_ROUTINE bool _Watchdog_Is_valid_timespec( const struct timespec *ts @@ -362,34 +362,11 @@ RTEMS_INLINE_ROUTINE const struct timespec * _Watchdog_Future_timespec( return now; } -RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_monotonic_timespec( +RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_timespec( const struct timespec *ts ) { - return ts->tv_sec >= _Watchdog_Monotonic_max_seconds; -} - -RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Monotonic_from_timespec( - const struct timespec *ts -) -{ - uint64_t ticks; - - _Assert( _Watchdog_Is_valid_timespec( ts ) ); - _Assert( ts->tv_sec >= 0 ); - _Assert( !_Watchdog_Is_far_future_monotonic_timespec( ts ) ); - - ticks = (uint64_t) ts->tv_sec * _Watchdog_Ticks_per_second; - ticks += (unsigned long) ts->tv_nsec / _Watchdog_Nanoseconds_per_tick; - - return ticks; -} - -RTEMS_INLINE_ROUTINE bool _Watchdog_Is_far_future_realtime_timespec( - const struct timespec *ts -) -{ - return ts->tv_sec > WATCHDOG_REALTIME_MAX_SECONDS; + return ts->tv_sec > WATCHDOG_MAX_SECONDS; } RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Ticks_from_seconds( @@ -411,7 +388,7 @@ RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Ticks_from_timespec( _Assert( _Watchdog_Is_valid_timespec( ts ) ); _Assert( ts->tv_sec >= 0 ); - _Assert( !_Watchdog_Is_far_future_realtime_timespec( ts ) ); + _Assert( !_Watchdog_Is_far_future_timespec( ts ) ); ticks = (uint64_t) ts->tv_sec; ticks <<= WATCHDOG_BITS_FOR_1E9_NANOSECONDS; @@ -457,7 +434,7 @@ RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert_ticks( Watchdog_Header *header; uint64_t expire; - header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; + header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ]; _Watchdog_Set_CPU( the_watchdog, cpu ); @@ -468,46 +445,19 @@ RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert_ticks( return expire; } -RTEMS_INLINE_ROUTINE bool _Watchdog_Per_CPU_lazy_insert_monotonic( - Watchdog_Control *the_watchdog, - Per_CPU_Control *cpu, - uint64_t expire -) -{ - ISR_lock_Context lock_context; - Watchdog_Header *header; - bool insert; - - header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; - - _Watchdog_Set_CPU( the_watchdog, cpu ); - - _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context ); - insert = ( expire > cpu->Watchdog.ticks ); - - if ( insert ) { - _Watchdog_Insert(header, the_watchdog, expire); - } - - _Watchdog_Per_CPU_release_critical( cpu, &lock_context ); - return insert; -} - -RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert_realtime( +RTEMS_INLINE_ROUTINE uint64_t _Watchdog_Per_CPU_insert( Watchdog_Control *the_watchdog, Per_CPU_Control *cpu, + Watchdog_Header *header, uint64_t expire ) { - ISR_lock_Context lock_context; - Watchdog_Header *header; - - header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ]; + ISR_lock_Context lock_context; _Watchdog_Set_CPU( the_watchdog, cpu ); _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context ); - _Watchdog_Insert(header, the_watchdog, expire); + _Watchdog_Insert( header, the_watchdog, expire ); _Watchdog_Per_CPU_release_critical( cpu, &lock_context ); return expire; } @@ -528,21 +478,7 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove( _Watchdog_Per_CPU_release_critical( cpu, &lock_context ); } -RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_monotonic( - Watchdog_Control *the_watchdog -) -{ - Per_CPU_Control *cpu; - - cpu = _Watchdog_Get_CPU( the_watchdog ); - _Watchdog_Per_CPU_remove( - the_watchdog, - cpu, - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ] - ); -} - -RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_realtime( +RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_ticks( Watchdog_Control *the_watchdog ) { @@ -552,7 +488,7 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Per_CPU_remove_realtime( _Watchdog_Per_CPU_remove( the_watchdog, cpu, - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ] + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ] ); } diff --git a/cpukit/posix/src/alarm.c b/cpukit/posix/src/alarm.c index fcf8c1569a..bbfc96d31d 100644 --- a/cpukit/posix/src/alarm.c +++ b/cpukit/posix/src/alarm.c @@ -77,14 +77,14 @@ unsigned int alarm( now = cpu->Watchdog.ticks; remaining = (unsigned long) _Watchdog_Cancel( - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ], the_watchdog, now ); if ( ticks != 0 ) { _Watchdog_Insert( - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ], the_watchdog, now + ticks ); diff --git a/cpukit/posix/src/nanosleep.c b/cpukit/posix/src/nanosleep.c index 5bd1b00aa9..7613df92d1 100644 --- a/cpukit/posix/src/nanosleep.c +++ b/cpukit/posix/src/nanosleep.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -93,7 +93,7 @@ int clock_nanosleep( ); } } else { - _TOD_Get_zero_based_uptime_as_timespec( &uptime ); + _Timecounter_Nanouptime( &uptime ); end = _Watchdog_Future_timespec( &uptime, rqtp ); _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec( &queue_context, @@ -119,7 +119,7 @@ int clock_nanosleep( if ( eno == EINTR ) { struct timespec actual_end; - _TOD_Get_zero_based_uptime_as_timespec( &actual_end ); + _Timecounter_Nanouptime( &actual_end ); if ( _Timespec_Less_than( &actual_end, end ) ) { _Timespec_Subtract( &actual_end, end, rmtp ); diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c index 43ed140b11..e05d4f3d19 100644 --- a/cpukit/posix/src/pthread.c +++ b/cpukit/posix/src/pthread.c @@ -69,7 +69,7 @@ void _POSIX_Threads_Sporadic_timer( Watchdog_Control *watchdog ) _Priority_Node_set_inactive( &api->Sporadic.Low_priority ); } - _Watchdog_Per_CPU_remove_monotonic( &api->Sporadic.Timer ); + _Watchdog_Per_CPU_remove_ticks( &api->Sporadic.Timer ); _POSIX_Threads_Sporadic_timer_insert( the_thread, api ); _Thread_Wait_release( the_thread, &queue_context ); @@ -141,7 +141,7 @@ static void _POSIX_Threads_Terminate_extension( Thread_Control *executing ) api = executing->API_Extensions[ THREAD_API_POSIX ]; _Thread_State_acquire( executing, &lock_context ); - _Watchdog_Per_CPU_remove_monotonic( &api->Sporadic.Timer ); + _Watchdog_Per_CPU_remove_ticks( &api->Sporadic.Timer ); _Thread_State_release( executing, &lock_context ); } diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c index 77e0ecaf48..b6854a080c 100644 --- a/cpukit/posix/src/pthreadsetschedparam.c +++ b/cpukit/posix/src/pthreadsetschedparam.c @@ -69,7 +69,7 @@ static int _POSIX_Set_sched_param( api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - _Watchdog_Per_CPU_remove_monotonic( &api->Sporadic.Timer ); + _Watchdog_Per_CPU_remove_ticks( &api->Sporadic.Timer ); _Priority_Node_set_priority( &the_thread->Real_priority, core_normal_prio ); diff --git a/cpukit/posix/src/sigtimedwait.c b/cpukit/posix/src/sigtimedwait.c index 72f4919be9..351edf0a1e 100644 --- a/cpukit/posix/src/sigtimedwait.c +++ b/cpukit/posix/src/sigtimedwait.c @@ -95,7 +95,7 @@ int sigtimedwait( if ( timeout != NULL ) { const struct timespec *end; - _TOD_Get_zero_based_uptime_as_timespec( &uptime ); + _Timecounter_Nanouptime( &uptime ); end = _Watchdog_Future_timespec( &uptime, timeout ); _Thread_queue_Context_set_enqueue_timeout_monotonic_timespec( &queue_context, diff --git a/cpukit/posix/src/timerdelete.c b/cpukit/posix/src/timerdelete.c index 5c21e1e80d..7670838ac2 100644 --- a/cpukit/posix/src/timerdelete.c +++ b/cpukit/posix/src/timerdelete.c @@ -56,7 +56,7 @@ int timer_delete( cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context ); ptimer->state = POSIX_TIMER_STATE_FREE; _Watchdog_Remove( - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ], &ptimer->Timer ); _POSIX_Timer_Release( cpu, &lock_context ); diff --git a/cpukit/posix/src/timersettime.c b/cpukit/posix/src/timersettime.c index 381e5002ce..9212e49740 100644 --- a/cpukit/posix/src/timersettime.c +++ b/cpukit/posix/src/timersettime.c @@ -42,7 +42,7 @@ static void _POSIX_Timer_Insert( _TOD_Get( &ptimer->time ); _Watchdog_Insert( - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ], &ptimer->Timer, cpu->Watchdog.ticks + ticks ); @@ -152,7 +152,7 @@ int timer_settime( /* Stop the timer */ _Watchdog_Remove( - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ], &ptimer->Timer ); diff --git a/cpukit/posix/src/ualarm.c b/cpukit/posix/src/ualarm.c index ead14d4469..371a961c94 100644 --- a/cpukit/posix/src/ualarm.c +++ b/cpukit/posix/src/ualarm.c @@ -107,7 +107,7 @@ useconds_t ualarm( now = cpu->Watchdog.ticks; remaining = (useconds_t) _Watchdog_Cancel( - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ], the_watchdog, now ); @@ -118,7 +118,7 @@ useconds_t ualarm( cpu = _Per_CPU_Get(); _Watchdog_Set_CPU( the_watchdog, cpu ); _Watchdog_Insert( - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ], the_watchdog, now + ticks_initial ); diff --git a/cpukit/rtems/src/ratemoncancel.c b/cpukit/rtems/src/ratemoncancel.c index 0a88310d09..ee556a3153 100644 --- a/cpukit/rtems/src/ratemoncancel.c +++ b/cpukit/rtems/src/ratemoncancel.c @@ -32,7 +32,7 @@ void _Rate_monotonic_Cancel( _Rate_monotonic_Acquire_critical( the_period, lock_context ); - _Watchdog_Per_CPU_remove_monotonic( &the_period->Timer ); + _Watchdog_Per_CPU_remove_ticks( &the_period->Timer ); the_period->state = RATE_MONOTONIC_INACTIVE; _Scheduler_Cancel_job( the_period->owner, diff --git a/cpukit/rtems/src/timercreate.c b/cpukit/rtems/src/timercreate.c index 444b07cfa5..0fff3d54cf 100644 --- a/cpukit/rtems/src/timercreate.c +++ b/cpukit/rtems/src/timercreate.c @@ -72,7 +72,7 @@ rtems_status_code _Timer_Fire( if ( _Timer_Is_interval_class( the_class ) ) { _Watchdog_Insert( - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ], &the_timer->Ticker, cpu->Watchdog.ticks + interval ); diff --git a/cpukit/rtems/src/timerreset.c b/cpukit/rtems/src/timerreset.c index 3718fffa66..6357160cf3 100644 --- a/cpukit/rtems/src/timerreset.c +++ b/cpukit/rtems/src/timerreset.c @@ -37,7 +37,7 @@ rtems_status_code rtems_timer_reset( if ( _Timer_Is_interval_class( the_timer->the_class ) ) { _Timer_Cancel( cpu, the_timer ); _Watchdog_Insert( - &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ], &the_timer->Ticker, cpu->Watchdog.ticks + the_timer->initial ); diff --git a/cpukit/score/src/threadqtimeout.c b/cpukit/score/src/threadqtimeout.c index 691f643493..0993fd4fe7 100644 --- a/cpukit/score/src/threadqtimeout.c +++ b/cpukit/score/src/threadqtimeout.c @@ -34,50 +34,13 @@ void _Thread_queue_Add_timeout_ticks( } } -static bool _Thread_queue_Lazy_insert_monotonic_timespec( +static void _Thread_queue_Add_timeout_timespec( + Thread_queue_Queue *queue, Thread_Control *the_thread, Per_CPU_Control *cpu_self, - const struct timespec *abstime -) -{ - uint64_t expire; - ISR_lock_Context lock_context; - bool insert; - - if ( abstime->tv_sec < 0 ) { - expire = 0; - } else if ( _Watchdog_Is_far_future_monotonic_timespec( abstime ) ) { - expire = WATCHDOG_MAXIMUM_TICKS; - } else { - expire = _Watchdog_Monotonic_from_timespec( abstime ); - } - - _ISR_lock_ISR_disable_and_acquire( - &the_thread->Timer.Lock, - &lock_context - ); - - the_thread->Timer.header = - &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; - the_thread->Timer.Watchdog.routine = _Thread_Timeout; - insert = _Watchdog_Per_CPU_lazy_insert_monotonic( - &the_thread->Timer.Watchdog, - cpu_self, - expire - ); - - _ISR_lock_Release_and_ISR_enable( - &the_thread->Timer.Lock, - &lock_context - ); - return insert; -} - -void _Thread_queue_Add_timeout_monotonic_timespec( - Thread_queue_Queue *queue, - Thread_Control *the_thread, - Per_CPU_Control *cpu_self, - Thread_queue_Context *queue_context + Thread_queue_Context *queue_context, + Watchdog_Header *header, + const struct timespec *now ) { const struct timespec *abstime; @@ -85,46 +48,17 @@ void _Thread_queue_Add_timeout_monotonic_timespec( abstime = queue_context->Timeout.arg; if ( _Watchdog_Is_valid_timespec( abstime ) ) { - if ( - !_Thread_queue_Lazy_insert_monotonic_timespec( - the_thread, - cpu_self, - abstime - ) - ) { - _Thread_Continue( the_thread, STATUS_TIMEOUT ); - } - } else { - _Thread_Continue( the_thread, STATUS_INVALID_NUMBER ); - } -} - -void _Thread_queue_Add_timeout_realtime_timespec( - Thread_queue_Queue *queue, - Thread_Control *the_thread, - Per_CPU_Control *cpu_self, - Thread_queue_Context *queue_context -) -{ - const struct timespec *abstime; - - abstime = queue_context->Timeout.arg; - - if ( _Watchdog_Is_valid_timespec( abstime ) ) { - uint64_t expire; - struct timespec now; + uint64_t expire; if ( abstime->tv_sec < 0 ) { expire = 0; - } else if ( _Watchdog_Is_far_future_realtime_timespec( abstime ) ) { + } else if ( _Watchdog_Is_far_future_timespec( abstime ) ) { expire = WATCHDOG_MAXIMUM_TICKS; } else { expire = _Watchdog_Ticks_from_timespec( abstime ); } - _Timecounter_Getnanotime( &now ); - - if ( expire > _Watchdog_Ticks_from_timespec( &now ) ) { + if ( expire > _Watchdog_Ticks_from_timespec( now ) ) { ISR_lock_Context lock_context; _ISR_lock_ISR_disable_and_acquire( @@ -132,12 +66,12 @@ void _Thread_queue_Add_timeout_realtime_timespec( &lock_context ); - the_thread->Timer.header = - &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ]; + the_thread->Timer.header = header; the_thread->Timer.Watchdog.routine = _Thread_Timeout; - _Watchdog_Per_CPU_insert_realtime( + _Watchdog_Per_CPU_insert( &the_thread->Timer.Watchdog, cpu_self, + header, expire ); @@ -152,3 +86,43 @@ void _Thread_queue_Add_timeout_realtime_timespec( _Thread_Continue( the_thread, STATUS_INVALID_NUMBER ); } } + +void _Thread_queue_Add_timeout_monotonic_timespec( + Thread_queue_Queue *queue, + Thread_Control *the_thread, + Per_CPU_Control *cpu_self, + Thread_queue_Context *queue_context +) +{ + struct timespec now; + + _Timecounter_Getnanouptime( &now ); + _Thread_queue_Add_timeout_timespec( + queue, + the_thread, + cpu_self, + queue_context, + &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], + &now + ); +} + +void _Thread_queue_Add_timeout_realtime_timespec( + Thread_queue_Queue *queue, + Thread_Control *the_thread, + Per_CPU_Control *cpu_self, + Thread_queue_Context *queue_context +) +{ + struct timespec now; + + _Timecounter_Getnanotime( &now ); + _Thread_queue_Add_timeout_timespec( + queue, + the_thread, + cpu_self, + queue_context, + &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ], + &now + ); +} diff --git a/cpukit/score/src/watchdogtick.c b/cpukit/score/src/watchdogtick.c index e9160f2ea1..2f11357019 100644 --- a/cpukit/score/src/watchdogtick.c +++ b/cpukit/score/src/watchdogtick.c @@ -70,7 +70,7 @@ void _Watchdog_Tick( Per_CPU_Control *cpu ) ++ticks; cpu->Watchdog.ticks = ticks; - header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; + header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ]; first = _Watchdog_Header_first( header ); if ( first != NULL ) { @@ -83,6 +83,20 @@ void _Watchdog_Tick( Per_CPU_Control *cpu ) ); } + header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; + first = _Watchdog_Header_first( header ); + + if ( first != NULL ) { + _Timecounter_Getnanouptime( &now ); + _Watchdog_Tickle( + header, + first, + _Watchdog_Ticks_from_timespec( &now ), + &cpu->Watchdog.Lock, + &lock_context + ); + } + header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ]; first = _Watchdog_Header_first( header ); diff --git a/testsuites/sptests/spintrcritical08/init.c b/testsuites/sptests/spintrcritical08/init.c index 559a1e421d..aab5701ed4 100644 --- a/testsuites/sptests/spintrcritical08/init.c +++ b/testsuites/sptests/spintrcritical08/init.c @@ -45,7 +45,7 @@ static rtems_timer_service_routine test_release_from_isr( ) { Per_CPU_Control *cpu = _Per_CPU_Get(); - Watchdog_Header *header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; + Watchdog_Header *header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ]; Watchdog_Control *watchdog = (Watchdog_Control *) header->first; if ( @@ -55,7 +55,7 @@ static rtems_timer_service_routine test_release_from_isr( ) { Thread_Wait_flags flags = _Thread_Wait_flags_get( thread ); - _Watchdog_Per_CPU_remove_monotonic( watchdog ); + _Watchdog_Per_CPU_remove_ticks( watchdog ); rtems_test_assert( getState() == RATE_MONOTONIC_ACTIVE ); diff --git a/testsuites/sptests/spintrcritical09/init.c b/testsuites/sptests/spintrcritical09/init.c index dc5b985ce7..63cfa2b5fb 100644 --- a/testsuites/sptests/spintrcritical09/init.c +++ b/testsuites/sptests/spintrcritical09/init.c @@ -39,7 +39,7 @@ static rtems_timer_service_routine test_release_from_isr( ) { Per_CPU_Control *cpu_self = _Per_CPU_Get(); - Watchdog_Header *header = &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; + Watchdog_Header *header = &cpu_self->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ]; Watchdog_Control *watchdog = (Watchdog_Control *) header->first; if ( diff --git a/testsuites/sptests/spwatchdog/init.c b/testsuites/sptests/spwatchdog/init.c index 5b6266d033..7b844d790a 100644 --- a/testsuites/sptests/spwatchdog/init.c +++ b/testsuites/sptests/spwatchdog/init.c @@ -59,7 +59,6 @@ static void test_watchdog_config( void ) { rtems_test_assert( _Watchdog_Nanoseconds_per_tick == 10000000 ); rtems_test_assert( _Watchdog_Ticks_per_second == 100 ); - rtems_test_assert( _Watchdog_Monotonic_max_seconds == 184467440737095516 ); rtems_test_assert( rtems_clock_get_ticks_per_second() == 100 ); #undef rtems_clock_get_ticks_per_second rtems_test_assert( rtems_clock_get_ticks_per_second() == 100 ); -- cgit v1.2.3