sched/wdog: fix switch_context caused error in wd_start()

Thead A:                     Thread B:
wd_start(wdogX)
wd_cancel
nxsched_cancel_timer  -->    wd_start(wdogX)
                             wd_cancel
                             add wdogX to g_wdactivelist
                      <--
add wdogX to g_wdactivelist

then, you will find wdogX add twice.

Change-Id: Icbf3b2badff20908e115c9134e2400cdcb32b1e0
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
ligd 2021-08-25 13:52:20 +08:00 committed by Masayuki Ishikawa
parent 1385ea7673
commit 9116ed9247
3 changed files with 14 additions and 10 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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