mirror of
https://github.com/apache/nuttx-apps.git
synced 2025-07-08 21:18:48 +08:00
testing/ostest: Fix timing assertions in wdog_test
This patch removed timing assertions in wdog_test. Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit is contained in:
parent
3d6785bcaf
commit
34e70e7f0c
@ -26,9 +26,10 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/wdog.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/****************************************************************************
|
||||
@ -36,12 +37,12 @@
|
||||
****************************************************************************/
|
||||
|
||||
#define WDOGTEST_RAND_ITER 1024
|
||||
#define WDOGTEST_THREAD_NR 8
|
||||
#define WDOGTEST_TOLERENT_LATENCY_US 5000
|
||||
#define WDOGTEST_THREAD_NR (CONFIG_SMP_NCPUS * 4)
|
||||
#define WDOGTEST_TOLERENT_TICK 10
|
||||
|
||||
#define wdtest_assert(x) _ASSERT(x, __FILE__, __LINE__)
|
||||
|
||||
#define wdtest_printf(...) printf(__VA_ARGS__)
|
||||
#define wdtest_printf(...) syslog(LOG_WARNING, __VA_ARGS__)
|
||||
|
||||
#define wdtest_delay(delay_ns) usleep(delay_ns / 1000 + 1)
|
||||
|
||||
@ -64,63 +65,131 @@ typedef struct wdtest_param_s
|
||||
#ifdef CONFIG_BUILD_FLAT
|
||||
static void wdtest_callback(wdparm_t param)
|
||||
{
|
||||
struct timespec tp;
|
||||
FAR wdtest_param_t *wdtest_param = (FAR wdtest_param_t *)param;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
/* Increment the callback count */
|
||||
|
||||
wdtest_param->callback_cnt += 1;
|
||||
wdtest_param->triggered_tick = clock_time2ticks(&tp);
|
||||
|
||||
/* Record the system tick at which the callback was triggered */
|
||||
|
||||
wdtest_param->triggered_tick = clock_systime_ticks();
|
||||
}
|
||||
|
||||
static void wdtest_checkdelay(sclock_t diff, sclock_t delay_tick)
|
||||
{
|
||||
/* Ensure the watchdog trigger time is not earlier than expected. */
|
||||
|
||||
wdtest_assert(diff - delay_tick >= 0);
|
||||
|
||||
/* If the timer latency exceeds the tolerance, print a warning. */
|
||||
|
||||
if (diff - delay_tick > WDOGTEST_TOLERENT_TICK)
|
||||
{
|
||||
wdtest_printf("WARNING: wdog latency ticks %lld "
|
||||
"(> %u may indicate timing error)\n",
|
||||
(long long)diff - delay_tick,
|
||||
WDOGTEST_TOLERENT_TICK);
|
||||
}
|
||||
}
|
||||
|
||||
static void wdtest_once(FAR struct wdog_s *wdog, FAR wdtest_param_t *param,
|
||||
sclock_t delay_ns)
|
||||
{
|
||||
uint64_t cnt;
|
||||
long long diff;
|
||||
clock_t wdset_tick;
|
||||
struct timespec tp;
|
||||
clock_t delay_ticks = (clock_t)NSEC2TICK((clock_t)delay_ns);
|
||||
uint64_t cnt;
|
||||
sclock_t diff;
|
||||
clock_t wdset_tick;
|
||||
irqstate_t flags;
|
||||
sclock_t delay_tick = (sclock_t)NSEC2TICK((clock_t)delay_ns);
|
||||
|
||||
wdtest_printf("wdtest_once %lld ns\n", (long long)delay_ns);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
/* Save the current callback count. */
|
||||
|
||||
wdset_tick = clock_time2ticks(&tp);
|
||||
cnt = param->callback_cnt;
|
||||
|
||||
wdtest_assert(wd_start(wdog, delay_ticks, wdtest_callback,
|
||||
/* Enter a critical section to prevent interruptions. */
|
||||
|
||||
flags = enter_critical_section();
|
||||
|
||||
/* Record the current system tick before setting the watchdog. */
|
||||
|
||||
wdset_tick = clock_systime_ticks();
|
||||
|
||||
wdtest_assert(wd_start(wdog, delay_tick, wdtest_callback,
|
||||
(wdparm_t)param) == OK);
|
||||
|
||||
wdtest_delay(delay_ns);
|
||||
leave_critical_section(flags);
|
||||
|
||||
diff = (long long)(param->triggered_tick - wdset_tick);
|
||||
/* Wait until the callback is triggered exactly once. */
|
||||
|
||||
wdtest_assert(cnt + 1 == param->callback_cnt);
|
||||
while (cnt + 1 != param->callback_cnt)
|
||||
{
|
||||
wdtest_delay(delay_ns);
|
||||
}
|
||||
|
||||
/* Ensure diff - delay_ticks >= 0. */
|
||||
/* Check if the delay is within the acceptable tolerance. */
|
||||
|
||||
wdtest_assert(diff - (long long)delay_ticks >= 0);
|
||||
wdtest_printf("wdtest_once latency ticks %lld\n", diff - delay_ticks);
|
||||
diff = (sclock_t)(param->triggered_tick - wdset_tick);
|
||||
|
||||
wdtest_checkdelay(diff, delay_tick);
|
||||
}
|
||||
|
||||
static void wdtest_rand(FAR struct wdog_s *wdog, FAR wdtest_param_t *param,
|
||||
sclock_t rand_ns)
|
||||
{
|
||||
int idx;
|
||||
sclock_t delay_ns;
|
||||
uint64_t cnt;
|
||||
int idx;
|
||||
sclock_t delay_ns;
|
||||
clock_t wdset_tick;
|
||||
sclock_t delay_tick;
|
||||
sclock_t diff;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Perform multiple iterations with random delays. */
|
||||
|
||||
for (idx = 0; idx < WDOGTEST_RAND_ITER; idx++)
|
||||
{
|
||||
delay_ns = rand() % rand_ns;
|
||||
wdtest_assert(wd_start(wdog, NSEC2TICK(delay_ns), wdtest_callback,
|
||||
(wdparm_t)param) == 0);
|
||||
cnt = param->callback_cnt;
|
||||
|
||||
/* Wait or Cancel 50/50 */
|
||||
/* Generate a random delay within the specified range. */
|
||||
|
||||
delay_ns = rand() % rand_ns;
|
||||
delay_tick = NSEC2TICK(delay_ns);
|
||||
|
||||
/* Enter critical section if the callback count is odd. */
|
||||
|
||||
if (cnt % 2)
|
||||
{
|
||||
flags = enter_critical_section();
|
||||
}
|
||||
|
||||
wdset_tick = clock_systime_ticks();
|
||||
wdtest_assert(wd_start(wdog, delay_tick, wdtest_callback,
|
||||
(wdparm_t)param) == 0);
|
||||
if (cnt % 2)
|
||||
{
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/* Decide to wait for the callback or cancel the watchdog. */
|
||||
|
||||
if (delay_ns % 2)
|
||||
{
|
||||
wdtest_delay(delay_ns);
|
||||
/* Wait for the callback. */
|
||||
|
||||
while (cnt + 1 != param->callback_cnt)
|
||||
{
|
||||
wdtest_delay(delay_ns);
|
||||
}
|
||||
|
||||
/* Check the delay if the callback count is odd. */
|
||||
|
||||
if (cnt % 2)
|
||||
{
|
||||
diff = (sclock_t)(param->triggered_tick - wdset_tick);
|
||||
wdtest_checkdelay(diff, delay_tick);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -131,14 +200,11 @@ static void wdtest_rand(FAR struct wdog_s *wdog, FAR wdtest_param_t *param,
|
||||
|
||||
static void wdtest_callback_recursive(wdparm_t param)
|
||||
{
|
||||
struct timespec tp;
|
||||
FAR wdtest_param_t *wdtest_param = (FAR wdtest_param_t *)param;
|
||||
sclock_t interval = wdtest_param->interval;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
|
||||
wdtest_param->callback_cnt += 1;
|
||||
wdtest_param->triggered_tick = clock_time2ticks(&tp);
|
||||
wdtest_param->triggered_tick = clock_systime_ticks();
|
||||
|
||||
wd_start(wdtest_param->wdog, interval,
|
||||
wdtest_callback_recursive, param);
|
||||
@ -149,24 +215,29 @@ static void wdtest_recursive(FAR struct wdog_s *wdog,
|
||||
sclock_t delay_ns,
|
||||
unsigned int times)
|
||||
{
|
||||
uint64_t cnt;
|
||||
struct timespec tp;
|
||||
clock_t wdset_tick;
|
||||
uint64_t cnt;
|
||||
clock_t wdset_tick;
|
||||
irqstate_t flags;
|
||||
|
||||
wdtest_printf("wdtest_recursive %lldus\n", (long long)delay_ns);
|
||||
|
||||
cnt = param->callback_cnt;
|
||||
|
||||
param->wdog = wdog;
|
||||
param->interval = (sclock_t)NSEC2TICK((clock_t)delay_ns);
|
||||
|
||||
wdtest_assert(param->interval >= 0);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
wdset_tick = clock_time2ticks(&tp);
|
||||
flags = enter_critical_section();
|
||||
|
||||
wdset_tick = clock_systime_ticks();
|
||||
|
||||
wdtest_assert(wd_start(param->wdog, param->interval,
|
||||
wdtest_callback_recursive,
|
||||
(wdparm_t)param) == OK);
|
||||
|
||||
leave_critical_section(flags);
|
||||
|
||||
wdtest_delay(times * delay_ns);
|
||||
|
||||
wdtest_assert(wd_cancel(param->wdog) == 0);
|
||||
@ -208,7 +279,6 @@ static void wdog_test_run(FAR wdtest_param_t *param)
|
||||
wdtest_once(&test_wdog, param, 100);
|
||||
wdtest_once(&test_wdog, param, 1000);
|
||||
wdtest_once(&test_wdog, param, 10000);
|
||||
wdtest_delay(10);
|
||||
|
||||
/* Delay > 0, middle 100us */
|
||||
|
||||
@ -242,11 +312,11 @@ static void wdog_test_run(FAR wdtest_param_t *param)
|
||||
|
||||
wdtest_assert(rest < delay && rest > (delay >> 1));
|
||||
|
||||
wdtest_printf("wd_start with maximum delay, cancel %lld\n",
|
||||
(long long)rest);
|
||||
|
||||
wdtest_assert(wd_cancel(&test_wdog) == 0);
|
||||
|
||||
wdtest_printf("wd_start with maximum delay, cancel OK, rest %lld\n",
|
||||
(long long)rest);
|
||||
|
||||
/* Delay wraparound (delay < 0) */
|
||||
|
||||
delay = (sclock_t)((clock_t)delay + 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user