From 243ea2a1e18084f827d81e58e133787534b6fb61 Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Fri, 16 Aug 2019 11:19:41 -0500 Subject: [PATCH] tests/kernel/sleep: relax upper bound to support additional delays Nordic platforms measure ticks in cycles of a 32 KiHz clock for which the minimum compare delay is 2 ticks. The test assumed an upper bound of four ticks delay per loop iteration, resulting from alignment at various layers. This delay is met on Nordic for tick rates at or below 16384, but is too short for the default 32768 Hz tick rate. Instrumentation confirms that the usleep test loop body on Nordic at 32 KiHz ticks takes 3 ticks as the optimum delay, only when a debug probe is active. In other circumstances it can take either 5 or 6 ticks, depending on timer alignment and stability. Relax the upper bound for platforms using this system timer at the highest rate. Closes #17965. Signed-off-by: Peter Bigot --- tests/kernel/sleep/src/usleep.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/tests/kernel/sleep/src/usleep.c b/tests/kernel/sleep/src/usleep.c index aca124c78da..70fbd63f162 100644 --- a/tests/kernel/sleep/src/usleep.c +++ b/tests/kernel/sleep/src/usleep.c @@ -15,24 +15,41 @@ #define RETRIES 10 +/* + * We need to know how many ticks will elapse when we ask for the + * shortest possible tick timeout. That's generally 1, but in some + * cases it may be more. On Nordic paths that take 5 or 6 ticks may + * be observed depending on clock stability and alignment. The base + * rate assumes 3 ticks for non-timeout effects so increase the + * maximum effect of timeout to 3 ticks on this platform. + */ + +#if defined(CONFIG_NRF_RTC_TIMER) && (CONFIG_SYS_CLOCK_TICKS_PER_SEC > 16384) +#define MAXIMUM_SHORTEST_TICKS 3 +#else +#define MAXIMUM_SHORTEST_TICKS 1 +#endif + /* * Theory of operation: we can't use absolute units (e.g., "sleep for * 10us") in testing k_usleep() because the granularity of sleeps is * highly dependent on the hardware's capabilities and kernel * configuration. Instead, we test that k_usleep() actually sleeps for - * the minimum possible duration. So, we loop k_usleep()ing for as - * many iterations as should comprise a second, and check to see that - * a total of one second has elapsed. + * the minimum possible duration, which is nominally two ticks. So, + * we loop k_usleep()ing for as many iterations as should comprise a + * second, and check to see that a total of one second has elapsed. */ #define LOOPS (CONFIG_SYS_CLOCK_TICKS_PER_SEC / 2) -/* It should never iterate faster than the tick rate. It might be as - * much as 4x slower on drivers with fast tick rates (each of the app, - * sleep, timeout and cycle layers may need to align). +/* It should never iterate faster than the tick rate. However the + * app, sleep, and timeout layers may each add a tick alignment with + * fast tick rates, and cycle layer may inject another to guarantee + * the timeout deadline is met. */ #define LOWER_BOUND_MS ((1000 * LOOPS) / CONFIG_SYS_CLOCK_TICKS_PER_SEC) -#define UPPER_BOUND_MS ((4 * 1000 * LOOPS) / CONFIG_SYS_CLOCK_TICKS_PER_SEC) +#define UPPER_BOUND_MS (((3 + MAXIMUM_SHORTEST_TICKS) * 1000 * LOOPS) \ + / CONFIG_SYS_CLOCK_TICKS_PER_SEC) void test_usleep(void) {