This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 9dad781d072ea48cf55bef428dcc8483100835dc Author: hujun5 <[email protected]> AuthorDate: Mon Jan 13 15:16:44 2025 +0800 sched/wdog: use small lock to protect g_wdactivelist reason: We would like to replace the critical section with a small lock. Signed-off-by: hujun5 <[email protected]> --- sched/wdog/wd_cancel.c | 10 +++++----- sched/wdog/wd_initialize.c | 2 ++ sched/wdog/wd_start.c | 27 +++++++++++++++++++-------- sched/wdog/wdog.h | 2 ++ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/sched/wdog/wd_cancel.c b/sched/wdog/wd_cancel.c index 3cfc960e8f..46ad9353b6 100644 --- a/sched/wdog/wd_cancel.c +++ b/sched/wdog/wd_cancel.c @@ -60,15 +60,10 @@ int wd_cancel(FAR struct wdog_s *wdog) { - irqstate_t flags; int ret; - flags = enter_critical_section(); - ret = wd_cancel_irq(wdog); - leave_critical_section(flags); - return ret; } @@ -91,12 +86,16 @@ int wd_cancel(FAR struct wdog_s *wdog) int wd_cancel_irq(FAR struct wdog_s *wdog) { + irqstate_t flags; bool head; + flags = spin_lock_irqsave(&g_wdspinlock); + /* Make sure that the watchdog is valid and still active. */ if (wdog == NULL || !WDOG_ISACTIVE(wdog)) { + spin_unlock_irqrestore(&g_wdspinlock, flags); return -EINVAL; } @@ -116,6 +115,7 @@ int wd_cancel_irq(FAR struct wdog_s *wdog) /* Mark the watchdog inactive */ wdog->func = NULL; + spin_unlock_irqrestore(&g_wdspinlock, flags); if (head) { diff --git a/sched/wdog/wd_initialize.c b/sched/wdog/wd_initialize.c index 563ad31c9d..dd35990f5a 100644 --- a/sched/wdog/wd_initialize.c +++ b/sched/wdog/wd_initialize.c @@ -34,6 +34,8 @@ * Public Data ****************************************************************************/ +spinlock_t g_wdspinlock = SP_UNLOCKED; + /* The g_wdactivelist data structure is a singly linked list ordered by * watchdog expiration time. When watchdog timers expire,the functions on * this linked list are removed and the function is called. diff --git a/sched/wdog/wd_start.c b/sched/wdog/wd_start.c index 739cec16a2..ca5b7bea33 100644 --- a/sched/wdog/wd_start.c +++ b/sched/wdog/wd_start.c @@ -114,8 +114,9 @@ static inline_function void wd_expiration(clock_t ticks) FAR struct wdog_s *wdog; irqstate_t flags; wdentry_t func; + wdparm_t arg; - flags = enter_critical_section(); + flags = spin_lock_irqsave(&g_wdspinlock); #ifdef CONFIG_SCHED_TICKLESS /* Increment the nested watchdog timer count to handle cases where wd_start @@ -147,12 +148,17 @@ static inline_function void wd_expiration(clock_t ticks) /* Indicate that the watchdog is no longer active. */ func = wdog->func; + arg = wdog->arg; wdog->func = NULL; /* Execute the watchdog function */ up_setpicbase(wdog->picbase); - CALL_FUNC(func, wdog->arg); + spin_unlock_irqrestore(&g_wdspinlock, flags); + + CALL_FUNC(func, arg); + + flags = spin_lock_irqsave(&g_wdspinlock); } #ifdef CONFIG_SCHED_TICKLESS @@ -161,7 +167,7 @@ static inline_function void wd_expiration(clock_t ticks) g_wdtimernested--; #endif - leave_critical_section(flags); + spin_unlock_irqrestore(&g_wdspinlock, flags); } /**************************************************************************** @@ -293,7 +299,7 @@ int wd_start_abstick(FAR struct wdog_s *wdog, clock_t ticks, * the critical section is established. */ - flags = enter_critical_section(); + flags = spin_lock_irqsave(&g_wdspinlock); #ifdef CONFIG_SCHED_TICKLESS /* We need to reassess timer if the watchdog list head has changed. */ @@ -314,8 +320,13 @@ int wd_start_abstick(FAR struct wdog_s *wdog, clock_t ticks, * then this will pick that new delay. */ + spin_unlock_irqrestore(&g_wdspinlock, flags); nxsched_reassess_timer(); } + else + { + spin_unlock_irqrestore(&g_wdspinlock, flags); + } #else UNUSED(reassess); @@ -328,8 +339,8 @@ int wd_start_abstick(FAR struct wdog_s *wdog, clock_t ticks, } wd_insert(wdog, ticks, wdentry, arg); + spin_unlock_irqrestore(&g_wdspinlock, flags); #endif - leave_critical_section(flags); sched_note_wdog(NOTE_WDOG_START, wdentry, (FAR void *)(uintptr_t)ticks); return OK; @@ -425,13 +436,13 @@ clock_t wd_timer(clock_t ticks, bool noswitches) wd_expiration(ticks); } - flags = enter_critical_section(); + flags = spin_lock_irqsave(&g_wdspinlock); /* Return the delay for the next watchdog to expire */ if (list_is_empty(&g_wdactivelist)) { - leave_critical_section(flags); + spin_unlock_irqrestore(&g_wdspinlock, flags); return 0; } @@ -442,7 +453,7 @@ clock_t wd_timer(clock_t ticks, bool noswitches) wdog = list_first_entry(&g_wdactivelist, struct wdog_s, node); ret = wdog->expired - ticks; - leave_critical_section(flags); + spin_unlock_irqrestore(&g_wdspinlock, flags); /* Return the delay for the next watchdog to expire */ diff --git a/sched/wdog/wdog.h b/sched/wdog/wdog.h index f7f4ca577e..d5520c747c 100644 --- a/sched/wdog/wdog.h +++ b/sched/wdog/wdog.h @@ -37,6 +37,7 @@ #include <nuttx/queue.h> #include <nuttx/wdog.h> #include <nuttx/list.h> +#include <nuttx/spinlock_type.h> /**************************************************************************** * Pre-processor Definitions @@ -64,6 +65,7 @@ extern "C" */ extern struct list_node g_wdactivelist; +extern spinlock_t g_wdspinlock; /**************************************************************************** * Public Function Prototypes
