This is an automated email from the ASF dual-hosted git repository.

ligd pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit b2a69ba781603fc7e1d477ea087b3e2f312a6858
Author: guoshengyuan1 <[email protected]>
AuthorDate: Thu Sep 25 20:10:45 2025 +0800

    sched: merge nxsched_suspend/resume_critmon
    
    Merge suspend and resume into one switch to optimize performance
    
    Co-authored-by: yinshengkai <[email protected]>
    Signed-off-by: guoshengyuan1 <[email protected]>
---
 sched/sched/sched.h               |   3 +-
 sched/sched/sched_critmonitor.c   | 129 +++++++++++++++++---------------------
 sched/sched/sched_switchcontext.c |   5 +-
 3 files changed, 59 insertions(+), 78 deletions(-)

diff --git a/sched/sched/sched.h b/sched/sched/sched.h
index 3d414f1e3fd..2ce145d1db7 100644
--- a/sched/sched/sched.h
+++ b/sched/sched/sched.h
@@ -416,8 +416,7 @@ void nxsched_process_cpuload_ticks(clock_t ticks);
 void nxsched_switch_context(FAR struct tcb_s *from, FAR struct tcb_s *to);
 
 #ifdef CONFIG_SCHED_CRITMONITOR
-void nxsched_resume_critmon(FAR struct tcb_s *tcb);
-void nxsched_suspend_critmon(FAR struct tcb_s *tcb);
+void nxsched_switch_critmon(FAR struct tcb_s *from, FAR struct tcb_s *to);
 void nxsched_update_critmon(FAR struct tcb_s *tcb);
 #endif
 
diff --git a/sched/sched/sched_critmonitor.c b/sched/sched/sched_critmonitor.c
index 9d8dc7d0379..610b07e35cd 100644
--- a/sched/sched/sched_critmonitor.c
+++ b/sched/sched/sched_critmonitor.c
@@ -262,99 +262,56 @@ void nxsched_critmon_csection(FAR struct tcb_s *tcb, bool 
state,
 #endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0 */
 
 /****************************************************************************
- * Name: nxsched_resume_critmon
+ * Name: nxsched_switch_critmon
  *
  * Description:
- *   Called when a thread resumes execution, perhaps re-establishing a
- *   critical section or a non-pre-emptible state.
+ *   Called when a thread is switched, update the critical monitor data.
  *
- * Assumptions:
- *   - Called within a critical section.
- *   - Might be called from an interrupt handler
- *
- ****************************************************************************/
-
-void nxsched_resume_critmon(FAR struct tcb_s *tcb)
-{
-  clock_t current = perf_gettime();
-
-  UNUSED(current);
-
-#if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0
-  tcb->run_start = current;
-#endif
-
-#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
-  /* Did this task disable pre-emption? */
-
-  if (nxsched_islocked_tcb(tcb))
-    {
-      /* Yes.. Save the start time */
-
-      tcb->preemp_start = current;
-    }
-#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION */
-
-#if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
-  /* Was this task in a critical section? */
-
-  if (tcb->irqcount > 0)
-    {
-      /* Yes.. Save the start time */
-
-      tcb->crit_start = current;
-    }
-#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION */
-}
-
-/****************************************************************************
- * Name: nxsched_suspend_critmon
- *
- * Description:
- *   Called when a thread suspends execution, perhaps terminating a
- *   critical section or a non-preemptible state.
+ * Input Parameters:
+ *   from - The thread that is being switched out.
+ *   to   - The thread that is being switched in.
  *
- * Assumptions:
- *   - Called within a critical section.
- *   - Might be called from an interrupt handler
+ * Returned Value:
+ *   None
  *
  ****************************************************************************/
 
-void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
+void nxsched_switch_critmon(FAR struct tcb_s *from, FAR struct tcb_s *to)
 {
   clock_t current = perf_gettime();
-  clock_t elapsed = current - tcb->run_start;
-  int cpu = this_cpu();
+  clock_t elapsed = current - from->run_start;
 
 #ifdef CONFIG_SCHED_CPULOAD_CRITMONITOR
   clock_t tick = elapsed * CLOCKS_PER_SEC / perf_getfreq();
-  nxsched_critmon_cpuload(tcb, current, tick);
+  nxsched_critmon_cpuload(from, current, tick);
 #endif
 
-  UNUSED(cpu);
-
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_THREAD >= 0
-  tcb->run_time += elapsed;
-  if (elapsed > tcb->run_max)
+  from->run_time += elapsed;
+  to->run_time = current;
+  if (elapsed > from->run_max)
     {
-      tcb->run_max = elapsed;
-      CHECK_THREAD(tcb->pid, elapsed);
+      from->run_max = elapsed;
+      CHECK_THREAD(from->pid, elapsed);
     }
 #endif
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
+
   /* Did this task disable preemption? */
 
-  if (nxsched_islocked_tcb(tcb))
+  if (nxsched_islocked_tcb(from))
     {
+      int cpu = this_cpu();
+
       /* Possibly re-enabling.. Check for the max elapsed time */
 
-      elapsed = current - tcb->preemp_start;
-      if (elapsed > tcb->preemp_max)
+      elapsed = current - from->preemp_start;
+      if (elapsed > from->preemp_max)
         {
-          tcb->preemp_max        = elapsed;
-          tcb->preemp_max_caller = tcb->preemp_caller;
-          CHECK_PREEMPTION(tcb->pid, elapsed);
+          from->preemp_max        = elapsed;
+          from->preemp_max_caller = from->preemp_caller;
+          CHECK_PREEMPTION(from->pid, elapsed);
         }
 
       /* Suspend percore preemptible statistic and if necessary will
@@ -366,21 +323,29 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
           g_preemp_max[cpu] = elapsed;
         }
     }
+
+  if (to->lockcount > 0)
+    {
+      to->premp_start = current;
+    }
 #endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION */
 
 #if CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION >= 0
+
   /* Is this task in a critical section? */
 
-  if (tcb->irqcount > 0)
+  if (from->irqcount > 0)
     {
+      int cpu = this_cpu();
+
       /* Possibly leaving .. Check for the max elapsed time */
 
-      elapsed = current - tcb->crit_start;
-      if (elapsed > tcb->crit_max)
+      elapsed = current - from->crit_start;
+      if (elapsed > from->crit_max)
         {
-          tcb->crit_max        = elapsed;
-          tcb->crit_max_caller = tcb->crit_caller;
-          CHECK_CSECTION(tcb->pid, elapsed);
+          from->crit_max        = elapsed;
+          from->crit_max_caller = from->crit_caller;
+          CHECK_CSECTION(from->pid, elapsed);
         }
 
       /* Check for the global max elapsed time */
@@ -390,7 +355,25 @@ void nxsched_suspend_critmon(FAR struct tcb_s *tcb)
           g_crit_max[cpu] = elapsed;
         }
     }
+
+  if (to->irqcount > 0)
+    {
+      to->crit_start = current;
+    }
+
 #endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_CSECTION */
+
+#if CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION >= 0
+
+  /* Did this task disable pre-emption? */
+
+  if (to->lockcount > 0)
+    {
+      /* Yes.. Save the start time */
+
+      to->premp_start = current;
+    }
+#endif /* CONFIG_SCHED_CRITMONITOR_MAXTIME_PREEMPTION */
 }
 
 void nxsched_update_critmon(FAR struct tcb_s *tcb)
diff --git a/sched/sched/sched_switchcontext.c 
b/sched/sched/sched_switchcontext.c
index 9b866272a27..0db4e01b984 100644
--- a/sched/sched/sched_switchcontext.c
+++ b/sched/sched/sched_switchcontext.c
@@ -28,7 +28,6 @@
 
 #include <nuttx/sched_note.h>
 
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -72,6 +71,7 @@ void nxsched_switch_context(FAR struct tcb_s *from, FAR 
struct tcb_s *to)
     {
       DEBUGVERIFY(nxsched_suspend_sporadic(from));
     }
+
   if ((to->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
     {
       DEBUGVERIFY(nxsched_resume_sporadic(to));
@@ -81,8 +81,7 @@ void nxsched_switch_context(FAR struct tcb_s *from, FAR 
struct tcb_s *to)
   /* Indicate that the task has been suspended */
 
 #ifdef CONFIG_SCHED_CRITMONITOR
-  nxsched_suspend_critmon(from);
-  nxsched_resume_critmon(to);
+  nxsched_switch_critmon(from, to);
 #endif
 
 #ifdef CONFIG_SCHED_INSTRUMENTATION

Reply via email to