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:
parent
1385ea7673
commit
9116ed9247
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user