From 5a9e39e358cfd9dcbb7f0a2e145cc09a31c40d8a Mon Sep 17 00:00:00 2001 From: yushuailong Date: Wed, 26 Aug 2026 00:46:19 +0800 Subject: [PATCH] sched/setscheduler: stop sporadic when switching away from SCHED_SPORADIC The policy flag bits were cleared before the switch statement, so the checks testing whether the task was previously SCHED_SPORADIC could never be true. As a result nxsched_stop_sporadic() was never called when a sporadic task switched to SCHED_FIFO/SCHED_RR, leaking the sporadic state, and a sporadic-to-sporadic reconfiguration ran initialize instead of reset. Clear the policy flag bits only after the previous policy has been evaluated, right before the new policy bits are set. Signed-off-by: yushuailong --- sched/sched/sched_setscheduler.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sched/sched/sched_setscheduler.c b/sched/sched/sched_setscheduler.c index 4efe6684b6f..181641c7b48 100644 --- a/sched/sched/sched_setscheduler.c +++ b/sched/sched/sched_setscheduler.c @@ -87,7 +87,7 @@ int process_sporadic(FAR struct tcb_s *tcb, if (repl_ticks < budget_ticks) #endif { - /* Initialize/reset current sporadic scheduling */ + /* Initialize or reset current sporadic scheduling */ if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC) @@ -103,6 +103,7 @@ int process_sporadic(FAR struct tcb_s *tcb, if (ret >= 0) { + tcb->flags &= ~TCB_FLAG_POLICY_MASK; tcb->flags |= TCB_FLAG_SCHED_SPORADIC; tcb->timeslice = budget_ticks; @@ -212,7 +213,6 @@ int nxsched_set_scheduler(pid_t pid, int policy, */ flags = enter_critical_section(); - tcb->flags &= ~TCB_FLAG_POLICY_MASK; switch (policy) { @@ -229,6 +229,7 @@ int nxsched_set_scheduler(pid_t pid, int policy, /* Save the FIFO scheduling parameters */ + tcb->flags &= ~TCB_FLAG_POLICY_MASK; tcb->flags |= TCB_FLAG_SCHED_FIFO; #if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) tcb->timeslice = 0; @@ -250,6 +251,7 @@ int nxsched_set_scheduler(pid_t pid, int policy, /* Save the round robin scheduling parameters */ + tcb->flags &= ~TCB_FLAG_POLICY_MASK; tcb->flags |= TCB_FLAG_SCHED_RR; tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); break; @@ -314,6 +316,7 @@ int sched_setscheduler(pid_t pid, int policy, FAR const struct sched_param *param) { int ret = nxsched_set_scheduler(pid, policy, param); + if (ret < 0) { set_errno(-ret);