From 7f7a3e8f70c46a2a5a5ef120909c8211840ef5cb Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 29 Jun 2017 14:36:26 +0200 Subject: tests: Move busy loop to test support Update #3056. --- cpukit/libmisc/Makefile.am | 1 + cpukit/libmisc/testsupport/test.h | 18 +++++- cpukit/libmisc/testsupport/testbusy.c | 107 ++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 cpukit/libmisc/testsupport/testbusy.c (limited to 'cpukit/libmisc') diff --git a/cpukit/libmisc/Makefile.am b/cpukit/libmisc/Makefile.am index d8fa47a2a5..6772dd1673 100644 --- a/cpukit/libmisc/Makefile.am +++ b/cpukit/libmisc/Makefile.am @@ -174,6 +174,7 @@ libstringto_a_SOURCES = stringto/stringtodouble.c stringto/stringtofloat.c \ noinst_LIBRARIES += libtestsupport.a libtestsupport_a_SOURCES = libtestsupport_a_SOURCES += testsupport/testbeginend.c +libtestsupport_a_SOURCES += testsupport/testbusy.c libtestsupport_a_SOURCES += testsupport/testextension.c libtestsupport_a_SOURCES += testsupport/testparallel.c diff --git a/cpukit/libmisc/testsupport/test.h b/cpukit/libmisc/testsupport/test.h index a32e2c42c1..d9ac6caf91 100644 --- a/cpukit/libmisc/testsupport/test.h +++ b/cpukit/libmisc/testsupport/test.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016 embedded brains GmbH. All rights reserved. + * Copyright (c) 2014, 2017 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -260,6 +260,22 @@ void rtems_test_parallel( size_t job_count ); +/** + * @brief Performs a busy loop with the specified iteration count. + * + * This function is optimized to not perform memory accesses and should have a + * small jitter. + * + * @param[in] count The iteration count. + */ +void rtems_test_busy(uint_fast32_t count); + +/** + * @brief Returns a count value for rtems_test_busy() which yields roughly a + * duration of one clock tick. + */ +uint_fast32_t rtems_test_get_one_tick_busy_count(void); + /** @} */ #ifdef __cplusplus diff --git a/cpukit/libmisc/testsupport/testbusy.c b/cpukit/libmisc/testsupport/testbusy.c new file mode 100644 index 0000000000..2d34a805dc --- /dev/null +++ b/cpukit/libmisc/testsupport/testbusy.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2014, 2017 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +static uint_fast32_t estimate_busy_loop_maximum( void ) +{ + uint_fast32_t units = 0; + uint_fast32_t initial = rtems_clock_get_ticks_since_boot(); + + while ( initial == rtems_clock_get_ticks_since_boot() ) { + ++units; + } + + return units; +} + +static uint_fast32_t wait_for_tick_change( void ) +{ + uint_fast32_t initial = rtems_clock_get_ticks_since_boot(); + uint_fast32_t now; + + do { + now = rtems_clock_get_ticks_since_boot(); + } while ( now == initial ); + + return now; +} + +/* + * It is important that we use actually use the same rtems_test_busy() function + * at the various places, since otherwise the obtained maximum value might be + * wrong. So, the compiler must not inline this function. + */ +RTEMS_NO_INLINE void rtems_test_busy( uint_fast32_t count ) +{ + uint_fast32_t i = 0; + + do { + __asm__ volatile (""); + ++i; + } while ( i < count ); +} + +uint_fast32_t rtems_test_get_one_tick_busy_count( void ) +{ + uint_fast32_t last; + uint_fast32_t now; + uint_fast32_t a; + uint_fast32_t b; + uint_fast32_t m; + + /* Choose a lower bound */ + a = 1; + + /* Estimate an upper bound */ + + wait_for_tick_change(); + b = 2 * estimate_busy_loop_maximum(); + + while ( true ) { + last = wait_for_tick_change(); + rtems_test_busy( b ); + now = rtems_clock_get_ticks_since_boot(); + + if ( now != last ) { + break; + } + + b *= 2; + last = now; + } + + /* Find a good value */ + do { + m = ( a + b ) / 2; + + last = wait_for_tick_change(); + rtems_test_busy( m ); + now = rtems_clock_get_ticks_since_boot(); + + if ( now != last ) { + b = m; + } else { + a = m; + } + } while ( b - a > 1 ); + + return m; +} -- cgit v1.2.3