summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-08-06 17:46:36 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-08-06 17:47:18 +0200
commit808cc9094513a505b1318add31b6ad2d61614b78 (patch)
treee6cc185e2cec23f9ae50f24dc97a1d677b385c96
parentad20d3d97d4283410d407bfd9051b232a63ded99 (diff)
tx-support TimecounterTick()
-rw-r--r--testsuites/validation/tx-support.h10
-rw-r--r--testsuites/validation/tx-timecounter.c45
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 );
+}