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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0bd1dc58a88 sched/sched_roundrobin.c: fix round-robin scheduling in 
SMP mode
0bd1dc58a88 is described below

commit 0bd1dc58a88d7a8423df98686a88b365e09a661d
Author: Filipe Cavalcanti <[email protected]>
AuthorDate: Wed Jan 14 15:50:02 2026 -0300

    sched/sched_roundrobin.c: fix round-robin scheduling in SMP mode
    
    In SMP mode, running tasks are in g_assignedtasks[cpu], not the
    ready-to-run list, so tcb->flink is NULL. When a round-robin timeslice
    expires, checking tcb->flink fails to find the next task.
    
    Fix by calling nxsched_switch_running() directly in SMP mode when the
    timeslice expires, which properly finds the next eligible task from the
    ready-to-run list.
    
    Signed-off-by: Filipe Cavalcanti <[email protected]>
---
 sched/sched/sched_roundrobin.c | 50 ++++++++++++++++++++++++++----------------
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/sched/sched/sched_roundrobin.c b/sched/sched/sched_roundrobin.c
index 350777744de..43dc6fcfdf1 100644
--- a/sched/sched/sched_roundrobin.c
+++ b/sched/sched/sched_roundrobin.c
@@ -180,33 +180,45 @@ clock_t nxsched_process_roundrobin(FAR struct tcb_s *tcb, 
clock_t ticks,
            * give that task a shot.
            */
 
-          if (tcb->flink &&
-              tcb->flink->sched_priority >= tcb->sched_priority)
-            {
-              FAR struct tcb_s *rtcb = this_task();
-
-              /* Just resetting the task priority to its current value.
-               * This will cause the task to be rescheduled behind any
-               * other tasks at the same priority.
-               */
+          FAR struct tcb_s *rtcb = this_task();
 
 #ifdef CONFIG_SMP
-              DEBUGASSERT(tcb->task_state == TSTATE_TASK_RUNNING);
-              if (tcb->cpu != this_cpu())
-                {
-                  nxsched_smp_call_init(&g_call_data,
-                                        nxsched_roundrobin_handler,
-                                        (FAR void *)(uintptr_t)tcb->pid);
-                  nxsched_smp_call_single_async(tcb->cpu, &g_call_data);
-                }
-              else if (nxsched_switch_running(tcb->cpu, true))
+          /* In SMP mode, the running task is in g_assignedtasks[cpu], not
+           * in the ready-to-run list.  Therefore, tcb->flink is NULL and
+           * we cannot check it to find the next task.  If the task is
+           * running on a different CPU, send an SMP call to that CPU.
+           * Otherwise, directly call nxsched_switch_running() to find the
+           * directly call nxsched_switch_running() to find the next eligible
+           * task from the ready-to-run list and switch to it.
+           */
+
+          DEBUGASSERT(tcb->task_state == TSTATE_TASK_RUNNING);
+          if (tcb->cpu != this_cpu())
+            {
+              nxsched_smp_call_init(&g_call_data,
+                                    nxsched_roundrobin_handler,
+                                    (FAR void *)(uintptr_t)tcb->pid);
+              nxsched_smp_call_single_async(tcb->cpu, &g_call_data);
+            }
+          else if (nxsched_switch_running(tcb->cpu, true))
+            {
+              up_switch_context(this_task(), rtcb);
+            }
 #else
+          /* Just resetting the task priority to its current value.
+           * This will cause the task to be rescheduled behind any
+           * other tasks at the same priority.
+           */
+
+          if (tcb->flink &&
+              tcb->flink->sched_priority >= tcb->sched_priority)
+            {
               if (nxsched_reprioritize_rtr(tcb, tcb->sched_priority))
-#endif
                 {
                   up_switch_context(this_task(), rtcb);
                 }
             }
+#endif
         }
     }
   else if (tcb->timeslice == 0)

Reply via email to