mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 20:08:15 +08:00
Sporadic Scheduler: Ensure that the replenishment period is greater than or equal to the budget period
This commit is contained in:
@@ -227,9 +227,6 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
|
|||||||
{
|
{
|
||||||
FAR struct pthread_tcb_s *ptcb;
|
FAR struct pthread_tcb_s *ptcb;
|
||||||
FAR struct join_s *pjoin;
|
FAR struct join_s *pjoin;
|
||||||
#ifdef CONFIG_SCHED_SPORADIC
|
|
||||||
int ticks;
|
|
||||||
#endif
|
|
||||||
int priority;
|
int priority;
|
||||||
int policy;
|
int policy;
|
||||||
int errcode;
|
int errcode;
|
||||||
@@ -308,6 +305,9 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
|
|||||||
if (attr->inheritsched == PTHREAD_INHERIT_SCHED)
|
if (attr->inheritsched == PTHREAD_INHERIT_SCHED)
|
||||||
{
|
{
|
||||||
struct sched_param param;
|
struct sched_param param;
|
||||||
|
#ifdef CONFIG_SCHED_SPORADIC
|
||||||
|
int ticks;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Get the priority (and any other scheduling parameters) for this
|
/* Get the priority (and any other scheduling parameters) for this
|
||||||
* thread.
|
* thread.
|
||||||
@@ -352,16 +352,42 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
|
|||||||
policy = attr->policy;
|
policy = attr->policy;
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_SPORADIC
|
#ifdef CONFIG_SCHED_SPORADIC
|
||||||
/* Save the sporadic scheduling parameters */
|
if (policy == SCHED_SPORADIC)
|
||||||
|
{
|
||||||
|
int repl_ticks;
|
||||||
|
int budget_ticks;
|
||||||
|
|
||||||
ptcb->cmn.low_priority = attr->low_priority;
|
/* Convert timespec values to system clock ticks */
|
||||||
ptcb->cmn.max_repl = attr->max_repl;
|
|
||||||
|
|
||||||
(void)clock_time2ticks(&attr->repl_period, &ticks);
|
(void)clock_time2ticks(&attr->repl_period, &repl_ticks);
|
||||||
ptcb->cmn.repl_period = ticks;
|
(void)clock_time2ticks(&attr->budget, &budget_ticks);
|
||||||
|
|
||||||
(void)clock_time2ticks(&attr->budget, &ticks);
|
/* The replenishment period must be greater than or equal to the
|
||||||
ptcb->cmn.budget = ticks;
|
* budget period.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (repl_ticks < budget_ticks)
|
||||||
|
{
|
||||||
|
errcode = EINVAL;
|
||||||
|
goto errout_with_join;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the sporadic scheduling parameters */
|
||||||
|
|
||||||
|
ptcb->cmn.low_priority = attr->low_priority;
|
||||||
|
ptcb->cmn.max_repl = attr->max_repl;
|
||||||
|
ptcb->cmn.repl_period = repl_ticks;
|
||||||
|
ptcb->cmn.budget = budget_ticks;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Ignore sporadic scheduling parameters */
|
||||||
|
|
||||||
|
ptcb->cmn.low_priority = 0;
|
||||||
|
ptcb->cmn.max_repl = 0;
|
||||||
|
ptcb->cmn.repl_period = 0;
|
||||||
|
ptcb->cmn.budget = 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,14 +86,15 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param)
|
|||||||
{
|
{
|
||||||
FAR struct tcb_s *rtcb;
|
FAR struct tcb_s *rtcb;
|
||||||
FAR struct tcb_s *tcb;
|
FAR struct tcb_s *tcb;
|
||||||
|
int errcode;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Verify that the requested priority is in the valid range */
|
/* Verify that the requested priority is in the valid range */
|
||||||
|
|
||||||
if (!param)
|
if (!param)
|
||||||
{
|
{
|
||||||
set_errno(EINVAL);
|
errcode = EINVAL;
|
||||||
return ERROR;
|
goto errout_with_errcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prohibit modifications to the head of the ready-to-run task
|
/* Prohibit modifications to the head of the ready-to-run task
|
||||||
@@ -110,18 +111,17 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param)
|
|||||||
tcb = rtcb;
|
tcb = rtcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The pid is not the calling task, we will have to search for it */
|
/* The PID is not the calling task, we will have to search for it */
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tcb = sched_gettcb(pid);
|
tcb = sched_gettcb(pid);
|
||||||
if (!tcb)
|
if (!tcb)
|
||||||
{
|
{
|
||||||
/* No task with this pid was found */
|
/* No task with this PID was found */
|
||||||
|
|
||||||
set_errno(ESRCH);
|
errcode = ESRCH;
|
||||||
sched_unlock();
|
goto errout_with_lock;
|
||||||
return ERROR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,20 +130,34 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param)
|
|||||||
|
|
||||||
if ((rtcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
|
if ((rtcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
|
||||||
{
|
{
|
||||||
int ticks;
|
int repl_ticks;
|
||||||
|
int budget_ticks;
|
||||||
|
|
||||||
DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX);
|
DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX);
|
||||||
|
|
||||||
|
/* Convert timespec values to system clock ticks */
|
||||||
|
|
||||||
|
(void)clock_time2ticks(¶m->sched_ss_repl_period, &repl_ticks);
|
||||||
|
(void)clock_time2ticks(¶m->sched_ss_init_budget, &budget_ticks);
|
||||||
|
|
||||||
|
/* The replenishment period must be greater than or equal to the
|
||||||
|
* budget period.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (repl_ticks < budget_ticks)
|
||||||
|
{
|
||||||
|
errcode = EINVAL;
|
||||||
|
goto errout_with_lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the sporadic scheduling parameters */
|
||||||
|
|
||||||
tcb->flags |= TCB_FLAG_SCHED_SPORADIC;
|
tcb->flags |= TCB_FLAG_SCHED_SPORADIC;
|
||||||
tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
|
tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
|
||||||
tcb->low_priority = param->sched_ss_low_priority;
|
tcb->low_priority = param->sched_ss_low_priority;
|
||||||
tcb->max_repl = param->sched_ss_max_repl;
|
tcb->max_repl = param->sched_ss_max_repl;
|
||||||
|
tcb->repl_period = repl_ticks;
|
||||||
(void)clock_time2ticks(¶m->sched_ss_repl_period, &ticks);
|
tcb->budget = budget_ticks;
|
||||||
tcb->repl_period = ticks;
|
|
||||||
|
|
||||||
(void)clock_time2ticks(¶m->sched_ss_init_budget, &ticks);
|
|
||||||
tcb->budget = ticks;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -154,9 +168,18 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Then perform the reprioritization */
|
/* Then perform the reprioritization */
|
||||||
|
|
||||||
ret = sched_reprioritize(tcb, param->sched_priority);
|
ret = sched_reprioritize(tcb, param->sched_priority);
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
errout_with_lock:
|
||||||
|
set_errno(errcode);
|
||||||
|
sched_unlock();
|
||||||
|
return ERROR;
|
||||||
|
|
||||||
|
errout_with_errcode:
|
||||||
|
set_errno(errcode);
|
||||||
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,20 +166,35 @@ int sched_setscheduler(pid_t pid, int policy,
|
|||||||
#ifdef CONFIG_SCHED_SPORADIC
|
#ifdef CONFIG_SCHED_SPORADIC
|
||||||
case SCHED_SPORADIC:
|
case SCHED_SPORADIC:
|
||||||
{
|
{
|
||||||
int ticks;
|
int repl_ticks;
|
||||||
|
int budget_ticks;
|
||||||
|
|
||||||
DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX);
|
DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX);
|
||||||
|
|
||||||
|
/* Convert timespec values to system clock ticks */
|
||||||
|
|
||||||
|
(void)clock_time2ticks(¶m->sched_ss_repl_period, &repl_ticks);
|
||||||
|
(void)clock_time2ticks(¶m->sched_ss_init_budget, &budget_ticks);
|
||||||
|
|
||||||
|
/* The replenishment period must be greater than or equal to the
|
||||||
|
* budget period.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (repl_ticks < budget_ticks)
|
||||||
|
{
|
||||||
|
set_errno(EINVAL);
|
||||||
|
sched_unlock();
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the sporadic scheduling parameters */
|
||||||
|
|
||||||
tcb->flags |= TCB_FLAG_SCHED_SPORADIC;
|
tcb->flags |= TCB_FLAG_SCHED_SPORADIC;
|
||||||
tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
|
tcb->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
|
||||||
tcb->low_priority = param->sched_ss_low_priority;
|
tcb->low_priority = param->sched_ss_low_priority;
|
||||||
tcb->max_repl = param->sched_ss_max_repl;
|
tcb->max_repl = param->sched_ss_max_repl;
|
||||||
|
tcb->repl_period = repl_ticks;
|
||||||
(void)clock_time2ticks(¶m->sched_ss_repl_period, &ticks);
|
tcb->budget = budget_ticks;
|
||||||
tcb->repl_period = ticks;
|
|
||||||
|
|
||||||
(void)clock_time2ticks(¶m->sched_ss_init_budget, &ticks);
|
|
||||||
tcb->budget = ticks;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -197,13 +212,5 @@ int sched_setscheduler(pid_t pid, int policy,
|
|||||||
|
|
||||||
ret = sched_reprioritize(tcb, param->sched_priority);
|
ret = sched_reprioritize(tcb, param->sched_priority);
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
|
return (ret >= 0) ? OK : ERROR;
|
||||||
if (ret != OK)
|
|
||||||
{
|
|
||||||
return ERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user