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 <yyyusl@qq.com>
This commit is contained in:
yushuailong 2026-08-26 00:46:19 +08:00 committed by Alan C. Assis
parent 8affe54985
commit 5a9e39e358

View file

@ -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);