From bb751e2ea1d795c54ae14284fef46e21cf3f957c Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 18 May 2021 10:13:11 +0200 Subject: tx-support --- testsuites/validation/tx-support.c | 129 +++++++++++++++++++++++++++++++++++++ testsuites/validation/tx-support.h | 24 +++++++ 2 files changed, 153 insertions(+) diff --git a/testsuites/validation/tx-support.c b/testsuites/validation/tx-support.c index 2820a8c6d1..c6f66c5c5f 100644 --- a/testsuites/validation/tx-support.c +++ b/testsuites/validation/tx-support.c @@ -375,6 +375,64 @@ void WaitForExecutionStop( rtems_id task_id ) #endif } +void GetTaskTimerInfo( rtems_id id, TaskTimerInfo *info ) +{ + Thread_Control *thread; + + info->expire_ticks = 0; + info->expire_timespec.tv_sec = -1; + info->expire_timespec.tv_nsec = -1; + + thread = GetThread( id ); + + if ( thread != NULL ) { + ISR_lock_Context lock_context; + ISR_lock_Context lock_context_2; + Per_CPU_Control *cpu; + + _ISR_lock_ISR_disable_and_acquire( &thread->Timer.Lock, &lock_context ); + info->expire_ticks = thread->Timer.Watchdog.expire; +#if defined( RTEMS_SMP ) + cpu = thread->Timer.Watchdog.cpu; +#else + cpu = _Per_CPU_Get(); +#endif + _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context_2 ); + + if ( _Watchdog_Is_scheduled( &thread->Timer.Watchdog ) ) { + const Watchdog_Header *hdr; + + hdr = thread->Timer.header; + + if ( hdr == &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ] ) { + info->state = TASK_TIMER_TICKS; + } else { + _Watchdog_Ticks_to_timespec( + info->expire_ticks, + &info->expire_timespec + ); + + if ( hdr == &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ] ) { + info->state = TASK_TIMER_REALTIME; + } else { + T_quiet_eq_ptr( + hdr, + &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ] + ); + info->state = TASK_TIMER_MONOTONIC; + } + } + } else { + info->state = TASK_TIMER_INACTIVE; + } + + _Watchdog_Per_CPU_release_critical( cpu, &lock_context_2 ); + _ISR_lock_Release_and_ISR_enable( &thread->Timer.Lock, &lock_context ); + } else { + info->state = TASK_TIMER_INVALID; + } +} + #if defined( RTEMS_SMP ) static void DoWatchdogTick( void *arg ) { @@ -395,3 +453,74 @@ void ClockTick( void ) #endif _Thread_Dispatch_enable( cpu_self ); } + +static void FinalWatchdogTick( Per_CPU_Control *cpu ) +{ + ISR_lock_Context lock_context; + Watchdog_Header *header; + Watchdog_Control *first; + + _ISR_lock_ISR_disable_and_acquire( &cpu->Watchdog.Lock, &lock_context ); + + header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ]; + first = _Watchdog_Header_first( header ); + + if ( first != NULL ) { + _Watchdog_Tickle( + header, + first, + UINT64_MAX, + &cpu->Watchdog.Lock, + &lock_context + ); + } + + header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]; + first = _Watchdog_Header_first( header ); + + if ( first != NULL ) { + _Watchdog_Tickle( + header, + first, + UINT64_MAX, + &cpu->Watchdog.Lock, + &lock_context + ); + } + + header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ]; + first = _Watchdog_Header_first( header ); + + if ( first != NULL ) { + _Watchdog_Tickle( + header, + first, + UINT64_MAX, + &cpu->Watchdog.Lock, + &lock_context + ); + } + + _ISR_lock_Release_and_ISR_enable( &cpu->Watchdog.Lock, &lock_context ); +} + +#if defined( RTEMS_SMP ) +static void DoFinalWatchdogTick( void *arg ) +{ + (void) arg; + FinalWatchdogTick( _Per_CPU_Get() ); +} +#endif + +void FinalClockTick( void ) +{ + Per_CPU_Control *cpu_self; + + cpu_self = _Thread_Dispatch_disable(); +#if defined( RTEMS_SMP ) + _SMP_Broadcast_action( DoFinalWatchdogTick, NULL ); +#else + FinalWatchdogTick( cpu_self ); +#endif + _Thread_Dispatch_enable( cpu_self ); +} diff --git a/testsuites/validation/tx-support.h b/testsuites/validation/tx-support.h index 9e1ed9d54b..30bec43b43 100644 --- a/testsuites/validation/tx-support.h +++ b/testsuites/validation/tx-support.h @@ -167,8 +167,32 @@ struct _Thread_Control *GetThread( rtems_id id ); void WaitForExecutionStop( rtems_id task_id ); +typedef enum { + TASK_TIMER_INVALID, + TASK_TIMER_INACTIVE, + TASK_TIMER_TICKS, + TASK_TIMER_REALTIME, + TASK_TIMER_MONOTONIC +} TaskTimerState; + +typedef struct { + TaskTimerState state; + uint64_t expire_ticks; + struct timespec expire_timespec; +} TaskTimerInfo; + +void GetTaskTimerInfo( rtems_id id, TaskTimerInfo *info ); + void ClockTick( void ); +/** + * @brief Simulates a clock tick with the final expire time point of + * UINT64_MAX for all clocks. + * + * This function does not update the clock ticks counter. + */ +void FinalClockTick( void ); + typedef uint32_t ( *GetTimecountHandler )( void ); /** -- cgit v1.2.3