From 4cbc56eec5ea7900b0b64cfe76cbec114628fec4 Mon Sep 17 00:00:00 2001 From: ouyangxiangzhen Date: Mon, 12 Jan 2026 15:54:08 +0800 Subject: [PATCH] sched/wdog: Add wd_adjust_next_tick. This commit added wd_adjust_next_tick to simplify the scheduler. Signed-off-by: ouyangxiangzhen --- sched/wdog/wd_initialize.c | 1 + sched/wdog/wd_start.c | 4 ++- sched/wdog/wdog.h | 54 +++++++++++++++++++++++++++++++++++--- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/sched/wdog/wd_initialize.c b/sched/wdog/wd_initialize.c index c2d18193ac3..779fea13a86 100644 --- a/sched/wdog/wd_initialize.c +++ b/sched/wdog/wd_initialize.c @@ -43,6 +43,7 @@ struct list_node g_wdactivelist = LIST_INITIAL_VALUE(g_wdactivelist); #ifdef CONFIG_SCHED_TICKLESS bool g_wdtimernested; +clock_t g_wdexpired; #endif /**************************************************************************** diff --git a/sched/wdog/wd_start.c b/sched/wdog/wd_start.c index f261125f8c9..10e16545a30 100644 --- a/sched/wdog/wd_start.c +++ b/sched/wdog/wd_start.c @@ -114,6 +114,8 @@ static inline_function void wd_expiration(clock_t ticks) flags = enter_critical_section(); + wd_update_expire(ticks); + wd_set_nested(true); /* Process the watchdog at the head of the list as well as any @@ -154,7 +156,7 @@ static inline_function void wd_expiration(clock_t ticks) if (next_ticks != ticks) { - wd_timer_start(wd_next_expire()); + wd_timer_start(next_ticks); } leave_critical_section(flags); diff --git a/sched/wdog/wdog.h b/sched/wdog/wdog.h index efcb61bc23a..c320928bab5 100644 --- a/sched/wdog/wdog.h +++ b/sched/wdog/wdog.h @@ -63,6 +63,7 @@ extern struct list_node g_wdactivelist; #ifdef CONFIG_SCHED_TICKLESS extern bool g_wdtimernested; +extern clock_t g_wdexpired; #endif /**************************************************************************** @@ -70,16 +71,49 @@ extern bool g_wdtimernested; ****************************************************************************/ #ifdef CONFIG_SCHED_TICKLESS -# define wd_in_callback() (g_wdtimernested) -# define wd_set_nested(f) (g_wdtimernested = (f)) +# define wd_in_callback() (g_wdtimernested) +# define wd_set_nested(f) (g_wdtimernested = (f)) +# define wd_update_expire(expired) (g_wdexpired = (expired)) #else # define wd_in_callback() (false) # define wd_set_nested(f) +# define wd_update_expire(expired) #endif #ifdef CONFIG_SCHED_TICKLESS -static inline_function void wd_timer_start(clock_t next_tick) +static inline_function clock_t wd_adjust_next_tick(clock_t tick) { + clock_t next_tick = tick; +#ifdef CONFIG_SCHED_TICKLESS_LIMIT_MAX_SLEEP + clock_t interval = clock_compare(g_wdexpired, tick) ? + tick - g_wdexpired : 0u; + interval = interval <= g_oneshot_maxticks ? + interval : g_oneshot_maxticks; + next_tick = g_wdexpired + interval; +#endif + +#if CONFIG_TIMER_ADJUST_USEC > 0 + /* Normally, timer event cannot triggered on exact time due to the + * existence of interrupt latency. + * Assuming that the interrupt latency is distributed within + * [Best-Case Execution Time, Worst-Case Execution Time], + * we can set the timer adjustment value to the BCET to reduce the latency. + * After the adjustment, the timer interrupt latency will be + * [0, WCET - BCET]. + * Please use this carefully, if the timer adjustment value is not the + * best-case interrupt latency, it will immediately fired another timer + * interrupt, which may result in a much larger timer interrupt latency. + */ + + next_tick -= CONFIG_TIMER_ADJUST_USEC / USEC_PER_TICK; +#endif + + return next_tick; +} + +static inline_function void wd_timer_start(clock_t tick) +{ + clock_t next_tick = wd_adjust_next_tick(tick); #ifdef CONFIG_SCHED_TICKLESS_ALARM # ifndef CONFIG_ALARM_ARCH struct timespec ts; @@ -124,6 +158,20 @@ static inline_function clock_t wd_next_expire(void) * Public Function Prototypes ****************************************************************************/ +static inline_function clock_t wd_get_next_expire(clock_t curr) +{ + clock_t next = curr; + irqstate_t flags = enter_critical_section(); + + if (!list_is_empty(&g_wdactivelist)) + { + next = wd_next_expire(); + } + + leave_critical_section(flags); + return (sclock_t)(next - curr) <= 0 ? 0u : next; +} + /**************************************************************************** * Name: wd_timer *