Skip to content
Snippets Groups Projects
Commit 3b130607 authored by Gregory Nutt's avatar Gregory Nutt
Browse files

Sporadic Scheduler: Ensure that the replenishment period is greater than or...

Sporadic Scheduler:  Ensure that the replenishment period is greater than or equal to the budget period
parent 5baa7380
No related branches found
No related tags found
No related merge requests found
...@@ -227,9 +227,6 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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(&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->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(&param->sched_ss_repl_period, &ticks); tcb->budget = budget_ticks;
tcb->repl_period = ticks;
(void)clock_time2ticks(&param->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) ...@@ -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);
sched_unlock();
return ret;
errout_with_lock:
set_errno(errcode);
sched_unlock();
return ERROR;
ret = sched_reprioritize(tcb, param->sched_priority); errout_with_errcode:
sched_unlock(); set_errno(errcode);
return ret; return ERROR;
} }
...@@ -166,20 +166,35 @@ int sched_setscheduler(pid_t pid, int policy, ...@@ -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(&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->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(&param->sched_ss_repl_period, &ticks); tcb->budget = budget_ticks;
tcb->repl_period = ticks;
(void)clock_time2ticks(&param->sched_ss_init_budget, &ticks);
tcb->budget = ticks;
} }
break; break;
#endif #endif
...@@ -197,13 +212,5 @@ int sched_setscheduler(pid_t pid, int policy, ...@@ -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;
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment