zephyr/tests/kernel/common/src/clock.c
Alberto Escolar Piedras 74e9ee967a tests: kernel: common: Bugfix for POSIX arch in TICKLESS
In the POSIX architecture, with the inf_clock "SOC", time does
not pass while the CPU is running. Tests that require time to pass
while busy waiting should call k_busy_wait() or in some other way
set the CPU to idle. This test was setting the CPU to idle while
waiting for the next time slice. This is ok if the system tick
(timer) is active and awaking the CPU every system tick period.
But when configured in tickless mode that is not the case, and the
CPU was set to sleep for an indefinite amount of time.
This commit fixes it by using k_busy_wait(a few microseconds) inside
that busy wait loop instead.

Signed-off-by: Alberto Escolar Piedras <alpi@oticon.com>
2018-11-13 09:19:03 -05:00

138 lines
2.8 KiB
C

/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
#if defined(CONFIG_ARCH_POSIX)
#define ALIGN_MS_BOUNDARY \
do { \
u32_t t = k_uptime_get_32(); \
while (t == k_uptime_get_32()) \
k_busy_wait(50); \
} while (0)
#else
#define ALIGN_MS_BOUNDARY \
do { \
u32_t t = k_uptime_get_32(); \
while (t == k_uptime_get_32()) \
; \
} while (0)
#endif
/**
* @addtogroup kernel_common_tests
* @{
*/
/**
* @brief Test clock uptime APIs functionality
*
* @see k_uptime_get(), k_uptime_get_32(), k_uptime_delta()
* k_uptime_delta_32()
*/
void test_clock_uptime(void)
{
u64_t t64, t32;
s64_t d64 = 0;
/**TESTPOINT: uptime elapse*/
t64 = k_uptime_get();
while (k_uptime_get() < (t64 + 5))
#if defined(CONFIG_ARCH_POSIX)
k_busy_wait(50);
#else
;
#endif
/**TESTPOINT: uptime elapse lower 32-bit*/
t32 = k_uptime_get_32();
while (k_uptime_get_32() < (t32 + 5))
#if defined(CONFIG_ARCH_POSIX)
k_busy_wait(50);
#else
;
#endif
/**TESTPOINT: uptime straddled ms boundary*/
t32 = k_uptime_get_32();
ALIGN_MS_BOUNDARY;
zassert_true(k_uptime_get_32() > t32, NULL);
/**TESTPOINT: uptime delta*/
d64 = k_uptime_delta(&d64);
/* Note: this will stall if the systick period < 5ms */
while (k_uptime_delta(&d64) < 5)
#if defined(CONFIG_ARCH_POSIX)
k_busy_wait(50);
#else
;
#endif
/**TESTPOINT: uptime delta lower 32-bit*/
k_uptime_delta_32(&d64);
/* Note: this will stall if the systick period < 5ms */
while (k_uptime_delta_32(&d64) < 5)
#if defined(CONFIG_ARCH_POSIX)
k_busy_wait(50);
#else
;
#endif
/**TESTPOINT: uptime delta straddled ms boundary*/
k_uptime_delta_32(&d64);
ALIGN_MS_BOUNDARY;
zassert_true(k_uptime_delta_32(&d64) > 0, NULL);
}
/**
* @brief Test clock cycle functionality
*
* @see k_cycle_get_32(), k_uptime_get_32()
*/
void test_clock_cycle(void)
{
u32_t c32, c0, c1, t32;
/**TESTPOINT: cycle elapse*/
ALIGN_MS_BOUNDARY;
c32 = k_cycle_get_32();
/*break if cycle counter wrap around*/
while (k_cycle_get_32() > c32 &&
k_cycle_get_32() < (c32 + sys_clock_hw_cycles_per_tick()))
#if defined(CONFIG_ARCH_POSIX)
k_busy_wait(50);
#else
;
#endif
/**TESTPOINT: cycle/uptime cross check*/
c0 = k_cycle_get_32();
ALIGN_MS_BOUNDARY;
t32 = k_uptime_get_32();
while (t32 == k_uptime_get_32())
#if defined(CONFIG_ARCH_POSIX)
k_busy_wait(50);
#else
;
#endif
c1 = k_uptime_get_32();
/*avoid cycle counter wrap around*/
if (c1 > c0) {
/* delta cycle should be greater than 1 milli-second*/
zassert_true((c1 - c0) >
(sys_clock_hw_cycles_per_sec() / MSEC_PER_SEC),
NULL);
/* delta NS should be greater than 1 milli-second */
zassert_true(SYS_CLOCK_HW_CYCLES_TO_NS(c1 - c0) >
(NSEC_PER_SEC / MSEC_PER_SEC), NULL);
}
}
/**
* @}
*/