mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
sched/sched: Fix uninitialized sporadic params returned by nxsched_get_param()
When querying the calling task itself (pid == 0 or the caller's own pid), nxsched_get_param() only filled in sched_priority and never touched the SCHED_SPORADIC related members (sched_ss_low_priority, sched_ss_max_repl, sched_ss_repl_period and sched_ss_init_budget). With CONFIG_SCHED_SPORADIC enabled, the caller received uninitialized stack garbage in these fields, and a task running under the sporadic policy could not retrieve its own sporadic parameters. Fix this by factoring the sporadic parameter fill-in into a common helper nxsched_get_sporadic_param() shared by both the self-query and the lookup paths, so both paths now return identical information. The self-query path keeps its original fast-path behavior: no TCB lookup and a lock-free read of sched_priority. Only the read of the sporadic state is wrapped in a critical section, because tcb->sporadic may be freed concurrently, e.g. by sched_setscheduler() from another CPU switching the task away from SCHED_SPORADIC. Signed-off-by: yushuailong <yyyusl@qq.com>
This commit is contained in:
parent
f0c94bb64a
commit
f1f5e7dafd
1 changed files with 58 additions and 27 deletions
|
|
@ -36,6 +36,51 @@
|
|||
#include "clock/clock.h"
|
||||
#include "sched/sched.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxsched_get_sporadic_param
|
||||
*
|
||||
* Description:
|
||||
* Fill in the SCHED_SPORADIC related members of param from the TCB.
|
||||
* Must be called within a critical section since the sporadic scheduler
|
||||
* state may be modified concurrently.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
static void nxsched_get_sporadic_param(FAR struct tcb_s *tcb,
|
||||
FAR struct sched_param *param)
|
||||
{
|
||||
if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
|
||||
{
|
||||
FAR struct sporadic_s *sporadic = tcb->sporadic;
|
||||
DEBUGASSERT(sporadic != NULL);
|
||||
|
||||
/* Return parameters associated with SCHED_SPORADIC */
|
||||
|
||||
param->sched_ss_low_priority = (int)sporadic->low_priority;
|
||||
param->sched_ss_max_repl = (int)sporadic->max_repl;
|
||||
|
||||
clock_ticks2time(¶m->sched_ss_repl_period,
|
||||
sporadic->repl_period);
|
||||
clock_ticks2time(¶m->sched_ss_init_budget,
|
||||
sporadic->budget);
|
||||
}
|
||||
else
|
||||
{
|
||||
param->sched_ss_low_priority = 0;
|
||||
param->sched_ss_max_repl = 0;
|
||||
param->sched_ss_repl_period.tv_sec = 0;
|
||||
param->sched_ss_repl_period.tv_nsec = 0;
|
||||
param->sched_ss_init_budget.tv_sec = 0;
|
||||
param->sched_ss_init_budget.tv_nsec = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -81,14 +126,24 @@ int nxsched_get_param(pid_t pid, FAR struct sched_param *param)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Check if the task to restart is the calling task */
|
||||
/* Check if the PID is that of the calling task */
|
||||
|
||||
rtcb = this_task();
|
||||
if (pid == 0 || pid == rtcb->pid)
|
||||
{
|
||||
/* Return the priority if the calling task. */
|
||||
/* Return the priority of the calling task. */
|
||||
|
||||
param->sched_priority = (int)rtcb->sched_priority;
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
/* The sporadic state may be modified concurrently, e.g. by
|
||||
* sched_setparam() from another CPU, so it must be protected.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
nxsched_get_sporadic_param(rtcb, param);
|
||||
leave_critical_section(flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This PID is not for the calling task, we will have to look it up */
|
||||
|
|
@ -112,31 +167,7 @@ int nxsched_get_param(pid_t pid, FAR struct sched_param *param)
|
|||
param->sched_priority = (int)tcb->sched_priority;
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
if ((tcb->flags & TCB_FLAG_POLICY_MASK) ==
|
||||
TCB_FLAG_SCHED_SPORADIC)
|
||||
{
|
||||
FAR struct sporadic_s *sporadic = tcb->sporadic;
|
||||
DEBUGASSERT(sporadic != NULL);
|
||||
|
||||
/* Return parameters associated with SCHED_SPORADIC */
|
||||
|
||||
param->sched_ss_low_priority = (int)sporadic->low_priority;
|
||||
param->sched_ss_max_repl = (int)sporadic->max_repl;
|
||||
|
||||
clock_ticks2time(¶m->sched_ss_repl_period,
|
||||
sporadic->repl_period);
|
||||
clock_ticks2time(¶m->sched_ss_init_budget,
|
||||
sporadic->budget);
|
||||
}
|
||||
else
|
||||
{
|
||||
param->sched_ss_low_priority = 0;
|
||||
param->sched_ss_max_repl = 0;
|
||||
param->sched_ss_repl_period.tv_sec = 0;
|
||||
param->sched_ss_repl_period.tv_nsec = 0;
|
||||
param->sched_ss_init_budget.tv_sec = 0;
|
||||
param->sched_ss_init_budget.tv_nsec = 0;
|
||||
}
|
||||
nxsched_get_sporadic_param(tcb, param);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue