Sporadic Scheduler: Ensure that the replenishment period is greater than or equal to the budget period

This commit is contained in:
Gregory Nutt
2015-07-23 15:08:41 -06:00
parent 5baa738019
commit 3b1306078b
3 changed files with 100 additions and 44 deletions
+36 -10
View File
@@ -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 join_s *pjoin;
#ifdef CONFIG_SCHED_SPORADIC
int ticks;
#endif
int priority;
int policy;
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)
{
struct sched_param param;
#ifdef CONFIG_SCHED_SPORADIC
int ticks;
#endif
/* Get the priority (and any other scheduling parameters) for this
* thread.
@@ -352,16 +352,42 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
policy = attr->policy;
#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;
ptcb->cmn.max_repl = attr->max_repl;
/* Convert timespec values to system clock ticks */
(void)clock_time2ticks(&attr->repl_period, &ticks);
ptcb->cmn.repl_period = ticks;
(void)clock_time2ticks(&attr->repl_period, &repl_ticks);
(void)clock_time2ticks(&attr->budget, &budget_ticks);
(void)clock_time2ticks(&attr->budget, &ticks);
ptcb->cmn.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_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
}
+41 -18
View File
@@ -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 *tcb;
int errcode;
int ret;
/* Verify that the requested priority is in the valid range */
if (!param)
{
set_errno(EINVAL);
return ERROR;
errcode = EINVAL;
goto errout_with_errcode;
}
/* 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;
}
/* 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
{
tcb = sched_gettcb(pid);
if (!tcb)
{
/* No task with this pid was found */
/* No task with this PID was found */
set_errno(ESRCH);
sched_unlock();
return ERROR;
errcode = ESRCH;
goto errout_with_lock;
}
}
@@ -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)
{
int ticks;
int repl_ticks;
int budget_ticks;
DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX);
/* Convert timespec values to system clock ticks */
(void)clock_time2ticks(&param->sched_ss_repl_period, &repl_ticks);
(void)clock_time2ticks(&param->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->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
tcb->low_priority = param->sched_ss_low_priority;
tcb->max_repl = param->sched_ss_max_repl;
(void)clock_time2ticks(&param->sched_ss_repl_period, &ticks);
tcb->repl_period = ticks;
(void)clock_time2ticks(&param->sched_ss_init_budget, &ticks);
tcb->budget = ticks;
tcb->repl_period = repl_ticks;
tcb->budget = budget_ticks;
}
else
{
@@ -154,9 +168,18 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param)
}
#endif
/* Then perform the reprioritization */
/* Then perform the reprioritization */
ret = sched_reprioritize(tcb, param->sched_priority);
sched_unlock();
return ret;
ret = sched_reprioritize(tcb, param->sched_priority);
sched_unlock();
return ret;
errout_with_lock:
set_errno(errcode);
sched_unlock();
return ERROR;
errout_with_errcode:
set_errno(errcode);
return ERROR;
}
+23 -16
View File
@@ -166,20 +166,35 @@ int sched_setscheduler(pid_t pid, int policy,
#ifdef CONFIG_SCHED_SPORADIC
case SCHED_SPORADIC:
{
int ticks;
int repl_ticks;
int budget_ticks;
DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX);
/* Convert timespec values to system clock ticks */
(void)clock_time2ticks(&param->sched_ss_repl_period, &repl_ticks);
(void)clock_time2ticks(&param->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->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL);
tcb->low_priority = param->sched_ss_low_priority;
tcb->max_repl = param->sched_ss_max_repl;
(void)clock_time2ticks(&param->sched_ss_repl_period, &ticks);
tcb->repl_period = ticks;
(void)clock_time2ticks(&param->sched_ss_init_budget, &ticks);
tcb->budget = ticks;
tcb->repl_period = repl_ticks;
tcb->budget = budget_ticks;
}
break;
#endif
@@ -197,13 +212,5 @@ int sched_setscheduler(pid_t pid, int policy,
ret = sched_reprioritize(tcb, param->sched_priority);
sched_unlock();
if (ret != OK)
{
return ERROR;
}
else
{
return OK;
}
return (ret >= 0) ? OK : ERROR;
}