diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-08-06 17:46:36 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-08-06 17:47:18 +0200 |
commit | 808cc9094513a505b1318add31b6ad2d61614b78 (patch) | |
tree | e6cc185e2cec23f9ae50f24dc97a1d677b385c96 | |
parent | ad20d3d97d4283410d407bfd9051b232a63ded99 (diff) |
tx-support TimecounterTick()
-rw-r--r-- | testsuites/validation/tx-support.h | 10 | ||||
-rw-r--r-- | testsuites/validation/tx-timecounter.c | 45 |
2 files changed, 55 insertions, 0 deletions
diff --git a/testsuites/validation/tx-support.h b/testsuites/validation/tx-support.h index 1c78bf2c18..19467f5b99 100644 --- a/testsuites/validation/tx-support.h +++ b/testsuites/validation/tx-support.h @@ -211,6 +211,16 @@ void ClockTick( void ); */ void FinalClockTick( void ); +/** + * @brief Simulates a single clock tick using the software timecounter. + * + * In contrast to ClockTick(), this function updates also CLOCK_MONOTONIC and + * CLOCK_REALTIME to the next software timecounter clock tick time point. + * + * This function is designed for test suites not having a clock driver. + */ +void TimecounterTick( void ); + typedef uint32_t ( *GetTimecountHandler )( void ); /** diff --git a/testsuites/validation/tx-timecounter.c b/testsuites/validation/tx-timecounter.c index cecbddf0f0..c6738914a4 100644 --- a/testsuites/validation/tx-timecounter.c +++ b/testsuites/validation/tx-timecounter.c @@ -43,6 +43,9 @@ #include <rtems/sysinit.h> #include <rtems/timecounter.h> #include <rtems/score/atomic.h> +#include <rtems/score/percpu.h> +#include <rtems/score/smpimpl.h> +#include <rtems/score/threaddispatch.h> typedef struct { struct timecounter base; @@ -113,3 +116,45 @@ RTEMS_SYSINIT_ITEM( RTEMS_SYSINIT_DEVICE_DRIVERS, RTEMS_SYSINIT_ORDER_LAST ); + +static void DoTimecounterTick( void *arg ) +{ + (void) arg; + _Timecounter_Tick(); +} + +void TimecounterTick( void ) +{ + unsigned long counter_ticks_per_clock_tick; + Per_CPU_Control *cpu_self; + bool success; + + counter_ticks_per_clock_tick = + SOFTWARE_TIMECOUNTER_FREQUENCY / rtems_clock_get_ticks_per_second(); + cpu_self = _Thread_Dispatch_disable(); + + do { + unsigned long old_counter; + unsigned long new_counter; + + old_counter = _Atomic_Load_ulong( + &TimecounterInstance.counter, + ATOMIC_ORDER_RELAXED + ); + new_counter = old_counter + counter_ticks_per_clock_tick - + ( old_counter % counter_ticks_per_clock_tick ); + success = _Atomic_Compare_exchange_ulong( + &TimecounterInstance.counter, + &old_counter, + new_counter, + ATOMIC_ORDER_RELAXED, + ATOMIC_ORDER_RELAXED + ); + } while ( !success ); + + DoTimecounterTick( NULL ); +#if defined( RTEMS_SMP ) + _SMP_Othercast_action( DoTimecounterTick, NULL ); +#endif + _Thread_Dispatch_enable( cpu_self ); +} |