diff --git a/sched/sched/sched_timerexpiration.c b/sched/sched/sched_timerexpiration.c index 9b43c54e31..ce3348f6ca 100644 --- a/sched/sched/sched_timerexpiration.c +++ b/sched/sched/sched_timerexpiration.c @@ -344,7 +344,7 @@ static unsigned int nxsched_timer_process(unsigned int ticks, /* Process watchdogs */ - tmp = wd_timer(ticks); + tmp = wd_timer(ticks, noswitches); if (tmp > 0) { cmptime = tmp; diff --git a/sched/wdog/wd_start.c b/sched/wdog/wd_start.c index d285fc72ec..d7e2a27881 100644 --- a/sched/wdog/wd_start.c +++ b/sched/wdog/wd_start.c @@ -351,6 +351,7 @@ int wd_start(FAR struct wdog_s *wdog, int32_t delay, * in the interval that just expired is provided. Otherwise, * this function is called on each timer interrupt and a value of one * is implicit. + * noswitches - True: Can't do context switches now. * * Returned Value: * If CONFIG_SCHED_TICKLESS is defined then the number of ticks for the @@ -363,7 +364,7 @@ int wd_start(FAR struct wdog_s *wdog, int32_t delay, ****************************************************************************/ #ifdef CONFIG_SCHED_TICKLESS -unsigned int wd_timer(int ticks) +unsigned int wd_timer(int ticks, bool noswitches) { FAR struct wdog_s *wdog; #ifdef CONFIG_SMP @@ -387,12 +388,9 @@ unsigned int wd_timer(int ticks) /* Check if there are any active watchdogs to process */ - while (g_wdactivelist.head != NULL && ticks > 0) + wdog = (FAR struct wdog_s *)g_wdactivelist.head; + while (wdog != NULL && ticks > 0) { - /* Get the watchdog at the head of the list */ - - wdog = (FAR struct wdog_s *)g_wdactivelist.head; - #ifndef CONFIG_SCHED_TICKLESS_ALARM /* There is logic to handle the case where ticks is greater than * the watchdog lag, but if the scheduling is working properly @@ -411,8 +409,13 @@ unsigned int wd_timer(int ticks) ticks -= decr; g_wdtickbase += decr; - /* Check if the watchdog at the head of the list is ready to run */ + wdog = wdog->next; + } + /* Check if the watchdog at the head of the list is ready to run */ + + if (!noswitches) + { wd_expiration(); } @@ -423,7 +426,7 @@ unsigned int wd_timer(int ticks) /* Return the delay for the next watchdog to expire */ ret = g_wdactivelist.head ? - ((FAR struct wdog_s *)g_wdactivelist.head)->lag : 0; + MAX(((FAR struct wdog_s *)g_wdactivelist.head)->lag, 1) : 0; #ifdef CONFIG_SMP leave_critical_section(flags); diff --git a/sched/wdog/wdog.h b/sched/wdog/wdog.h index 24b75c76f9..c5279769d2 100644 --- a/sched/wdog/wdog.h +++ b/sched/wdog/wdog.h @@ -121,6 +121,7 @@ void weak_function wd_initialize(void); * in the interval that just expired is provided. Otherwise, * this function is called on each timer interrupt and a value of one * is implicit. + * noswitches - True: Can't do context switches now. * * Returned Value: * If CONFIG_SCHED_TICKLESS is defined then the number of ticks for the @@ -133,7 +134,7 @@ void weak_function wd_initialize(void); ****************************************************************************/ #ifdef CONFIG_SCHED_TICKLESS -unsigned int wd_timer(int ticks); +unsigned int wd_timer(int ticks, bool noswitches); #else void wd_timer(void); #endif