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

Reply via email to