From 3b1306078b57c5f6fa6141ecd3d80e4847c0b981 Mon Sep 17 00:00:00 2001 From: Gregory Nutt <gnutt@nuttx.org> Date: Thu, 23 Jul 2015 15:08:41 -0600 Subject: [PATCH] Sporadic Scheduler: Ensure that the replenishment period is greater than or equal to the budget period --- sched/pthread/pthread_create.c | 46 +++++++++++++++++++------ sched/sched/sched_setparam.c | 59 ++++++++++++++++++++++---------- sched/sched/sched_setscheduler.c | 39 ++++++++++++--------- 3 files changed, 100 insertions(+), 44 deletions(-) diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 86e3dd8d8d..9cea2af0e8 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -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 } diff --git a/sched/sched/sched_setparam.c b/sched/sched/sched_setparam.c index e75980c3b5..f7f193cdcf 100644 --- a/sched/sched/sched_setparam.c +++ b/sched/sched/sched_setparam.c @@ -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(¶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->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); tcb->low_priority = param->sched_ss_low_priority; tcb->max_repl = param->sched_ss_max_repl; - - (void)clock_time2ticks(¶m->sched_ss_repl_period, &ticks); - tcb->repl_period = ticks; - - (void)clock_time2ticks(¶m->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; + +errout_with_lock: + set_errno(errcode); + sched_unlock(); + return ERROR; - ret = sched_reprioritize(tcb, param->sched_priority); - sched_unlock(); - return ret; +errout_with_errcode: + set_errno(errcode); + return ERROR; } diff --git a/sched/sched/sched_setscheduler.c b/sched/sched/sched_setscheduler.c index f05fb39bc7..0c3c6a6f94 100644 --- a/sched/sched/sched_setscheduler.c +++ b/sched/sched/sched_setscheduler.c @@ -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(¶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->timeslice = MSEC2TICK(CONFIG_RR_INTERVAL); tcb->low_priority = param->sched_ss_low_priority; tcb->max_repl = param->sched_ss_max_repl; - - (void)clock_time2ticks(¶m->sched_ss_repl_period, &ticks); - tcb->repl_period = ticks; - - (void)clock_time2ticks(¶m->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; } -- GitLab