mirror of
https://github.com/apache/nuttx.git
synced 2026-05-19 03:03:37 +08:00
This is basically a complete redesign of the sporadic scheduling logic due to limitations in the initial design
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
NuttX TODO List (Last updated July 14, 2015)
|
||||
NuttX TODO List (Last updated July 25, 2015)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||
@@ -9,7 +9,7 @@ issues reated to each board port.
|
||||
|
||||
nuttx/
|
||||
|
||||
(11) Task/Scheduler (sched/)
|
||||
(12) Task/Scheduler (sched/)
|
||||
(1) Memory Management (mm/)
|
||||
(3) Signals (sched/signal, arch/)
|
||||
(2) pthreads (sched/pthread)
|
||||
@@ -213,6 +213,22 @@ o Task/Scheduler (sched/)
|
||||
Status: Open
|
||||
Priority: Medium-ish
|
||||
|
||||
Title: TICKLESS SCHEDULING INACCURACIES
|
||||
Description: Interval timers are set up to determine timing for round-
|
||||
robin and sporadic scheduling policies. In the timer
|
||||
interrupt mode, the budget remaining for the thread is
|
||||
decremented on each timer interrupt and so is always
|
||||
accurate to within one clock time. So when the task
|
||||
suspended, the remaining budget is accurate.
|
||||
|
||||
But in tickless mode, the budget is only updated on the
|
||||
expiration of the timer. So if the task is suspended by an
|
||||
asynchronous event, the budget will fail to decrement and the
|
||||
task will get a larger share of CPU that is deserves in those
|
||||
cases.
|
||||
Status: Open
|
||||
Priority: Low. I am not aware of any real world issues.
|
||||
|
||||
o Memory Managment (mm/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
+54
-19
@@ -116,6 +116,12 @@
|
||||
# undef HAVE_GROUP_MEMBERS
|
||||
#endif
|
||||
|
||||
/* Sporadic scheduling */
|
||||
|
||||
#ifndef CONFIG_SCHED_SPORADIC_MAXREPL
|
||||
# define CONFIG_SCHED_SPORADIC_MAXREPL 3
|
||||
#endif
|
||||
|
||||
/* Task Management Definitions **************************************************/
|
||||
/* Special task IDS. Any negative PID is invalid. */
|
||||
|
||||
@@ -234,10 +240,49 @@ typedef CODE void (*atexitfunc_t)(void);
|
||||
typedef CODE void (*onexitfunc_t)(int exitcode, FAR void *arg);
|
||||
#endif
|
||||
|
||||
/* struct sporadic_s *************************************************************/
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
|
||||
/* This structure represents oen replenishment interval. This is what is
|
||||
* received by each timeout handler.
|
||||
*/
|
||||
|
||||
struct sporadic_s;
|
||||
struct replenishment_s
|
||||
{
|
||||
FAR struct tcb_s *tcb; /* The parent TCB structure */
|
||||
struct wdog_s timer; /* Timer dedicated to this interval */
|
||||
bool active; /* True: replenishment instance is busy */
|
||||
};
|
||||
|
||||
/* This structure is an allocated "plug-in" to the main TCB structure. It is
|
||||
* allocated when the sporadic scheduling policy is assigned to a thread. Thus,
|
||||
* in the context of numerous threads of varying policies, there the overhead
|
||||
* from this significant allocation is only borne by the threads with the
|
||||
* sporadic scheduling policy.
|
||||
*/
|
||||
|
||||
struct sporadic_s
|
||||
{
|
||||
uint8_t hi_priority; /* Sporadic high priority */
|
||||
uint8_t low_priority; /* Sporadic low priority */
|
||||
uint8_t max_repl; /* Maximum number of replenishments */
|
||||
uint8_t nrepls; /* Number of active replenishments */
|
||||
uint32_t repl_period; /* Sporadic replenishment period */
|
||||
uint32_t budget; /* Sporadic execution budget period */
|
||||
uint32_t pending; /* Unrealized, pending execution time */
|
||||
|
||||
/* This is the list of replenishment intervals */
|
||||
|
||||
struct replenishment_s replenishments[CONFIG_SCHED_SPORADIC_MAXREPL];
|
||||
};
|
||||
|
||||
#endif /* CONFIG_SCHED_SPORADIC */
|
||||
|
||||
/* struct child_status_s *********************************************************/
|
||||
/* This structure is used to maintin information about child tasks.
|
||||
* pthreads work differently, they have join information. This is
|
||||
* only for child tasks.
|
||||
/* This structure is used to maintain information about child tasks. pthreads
|
||||
* work differently, they have join information. This is only for child tasks.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SCHED_CHILD_STATUS
|
||||
@@ -245,9 +290,9 @@ struct child_status_s
|
||||
{
|
||||
FAR struct child_status_s *flink;
|
||||
|
||||
uint8_t ch_flags; /* Child status: See CHILD_FLAG_* definitions */
|
||||
pid_t ch_pid; /* Child task ID */
|
||||
int ch_status; /* Child exit status */
|
||||
uint8_t ch_flags; /* Child status: See CHILD_FLAG_* defns */
|
||||
pid_t ch_pid; /* Child task ID */
|
||||
int ch_status; /* Child exit status */
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -478,20 +523,12 @@ struct tcb_s
|
||||
entry_t entry; /* Entry Point into the thread */
|
||||
uint8_t sched_priority; /* Current priority of the thread */
|
||||
|
||||
#if defined(CONFIG_PRIORITY_INHERITANCE) && CONFIG_PRIORITY_INHERITANCE > 0
|
||||
#ifdef CONFIG_PRIORITY_INHERITANCE
|
||||
#if CONFIG_SEM_NNESTPRIO > 0
|
||||
uint8_t npend_reprio; /* Number of nested reprioritizations */
|
||||
uint8_t pend_reprios[CONFIG_SEM_NNESTPRIO];
|
||||
#endif
|
||||
#if defined(CONFIG_PRIORITY_INHERITANCE) || defined(CONFIG_SCHED_SPORADIC)
|
||||
uint8_t base_priority; /* "Normal" priority of the thread */
|
||||
#endif
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
uint8_t hi_priority; /* Sporadic high priority */
|
||||
uint8_t low_priority; /* Sporadic low priority */
|
||||
#ifdef __REVISIT_REPLENISHMENTS
|
||||
uint8_t max_repl; /* Max. replenishments */
|
||||
uint8_t nrepl; /* Number replenishments remaining */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint8_t task_state; /* Current state of the thread */
|
||||
@@ -503,9 +540,7 @@ struct tcb_s
|
||||
/* interval remaining */
|
||||
#endif
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
uint32_t repl_period; /* Sporadic replenishment period */
|
||||
uint32_t budget; /* Sporadic execution budget */
|
||||
struct wdog_s low_dog; /* Times low-priority interval */
|
||||
FAR struct sporadic_s *sporadic; /* Sporadic scheduling parameters */
|
||||
#endif
|
||||
|
||||
FAR struct wdog_s *waitdog; /* All timed waits use this timer */
|
||||
|
||||
+11
-1
@@ -311,7 +311,17 @@ config SCHED_SPORADIC
|
||||
bool "Support sporadic scheduling"
|
||||
default n
|
||||
---help---
|
||||
Build in additional logic to support sporadic scheduling (SCHED_SPORADIC).
|
||||
Build in additional logic to support sporadic scheduling
|
||||
(SCHED_SPORADIC).
|
||||
|
||||
config SCHED_SPORADIC_MAXREPL
|
||||
int "Maximum number of replenishments"
|
||||
default 3
|
||||
range 1 255
|
||||
depends on SCHED_SPORADIC
|
||||
---help---
|
||||
Controls the size of allocated replenishment structures and, hence,
|
||||
also limits the maximum number of replenishments.
|
||||
|
||||
config TASK_NAME_SIZE
|
||||
int "Maximum task name size"
|
||||
|
||||
@@ -228,7 +228,7 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
|
||||
{
|
||||
FAR struct pthread_tcb_s *ptcb;
|
||||
FAR struct join_s *pjoin;
|
||||
int priority;
|
||||
struct sched_param param;
|
||||
int policy;
|
||||
int errcode;
|
||||
pid_t pid;
|
||||
@@ -298,18 +298,13 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
|
||||
goto errout_with_join;
|
||||
}
|
||||
|
||||
/* Should we use the priority and scheduler specified in the
|
||||
* pthread attributes? Or should we use the current thread's
|
||||
* priority and scheduler?
|
||||
/* Should we use the priority and scheduler specified in the pthread
|
||||
* attributes? Or should we use the current thread's priority and
|
||||
* scheduler?
|
||||
*/
|
||||
|
||||
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.
|
||||
*/
|
||||
@@ -321,8 +316,6 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
|
||||
goto errout_with_join;
|
||||
}
|
||||
|
||||
priority = param.sched_priority;
|
||||
|
||||
/* Get the scheduler policy for this thread */
|
||||
|
||||
policy = sched_getscheduler(0);
|
||||
@@ -331,71 +324,81 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr,
|
||||
errcode = get_errno();
|
||||
goto errout_with_join;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
/* Save the sporadic scheduling parameters */
|
||||
|
||||
ptcb->cmn.hi_priority = priority;
|
||||
ptcb->cmn.low_priority = param.sched_ss_low_priority;
|
||||
#ifdef __REVISIT_REPLENISHMENTS
|
||||
ptcb->cmn.max_repl = param.sched_ss_max_repl;
|
||||
#endif
|
||||
|
||||
(void)clock_time2ticks(¶m.sched_ss_repl_period, &ticks);
|
||||
ptcb->cmn.repl_period = ticks;
|
||||
|
||||
(void)clock_time2ticks(¶m.sched_ss_init_budget, &ticks);
|
||||
ptcb->cmn.budget = ticks;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the priority and scheduler from the attributes */
|
||||
/* Use the scheduler policy and policy the attributes */
|
||||
|
||||
priority = attr->priority;
|
||||
policy = attr->policy;
|
||||
policy = attr->policy;
|
||||
param.sched_priority = attr->priority;
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
if (policy == SCHED_SPORADIC)
|
||||
{
|
||||
int repl_ticks;
|
||||
int budget_ticks;
|
||||
|
||||
/* Convert timespec values to system clock ticks */
|
||||
|
||||
(void)clock_time2ticks(&attr->repl_period, &repl_ticks);
|
||||
(void)clock_time2ticks(&attr->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_join;
|
||||
}
|
||||
|
||||
/* Save the sporadic scheduling parameters */
|
||||
|
||||
ptcb->cmn.hi_priority = priority;
|
||||
ptcb->cmn.low_priority = attr->low_priority;
|
||||
#ifdef __REVISIT_REPLENISHMENTS
|
||||
ptcb->cmn.max_repl = attr->max_repl;
|
||||
#endif
|
||||
ptcb->cmn.repl_period = repl_ticks;
|
||||
ptcb->cmn.budget = budget_ticks;
|
||||
|
||||
/* And start the frist replenishment interval */
|
||||
|
||||
DEBUGVERIFY(sched_sporadic_start(&ptcb->cmn));
|
||||
}
|
||||
param.sched_ss_low_priority = attr->low_priority;
|
||||
param.sched_ss_max_repl = attr->max_repl;
|
||||
param.sched_ss_repl_period.tv_sec = attr->repl_period.tv_sec;
|
||||
param.sched_ss_repl_period.tv_nsec = attr->repl_period.tv_nsec;
|
||||
param.sched_ss_init_budget.tv_sec = attr->budget.tv_sec;
|
||||
param.sched_ss_init_budget.tv_nsec = attr->budget.tv_nsec;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
if (policy == SCHED_SPORADIC)
|
||||
{
|
||||
FAR struct sporadic_s *sporadic;
|
||||
int repl_ticks;
|
||||
int budget_ticks;
|
||||
|
||||
/* 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_join;
|
||||
}
|
||||
|
||||
/* Initialize the sporadic policy */
|
||||
|
||||
ret = sched_sporadic_initialize(&ptcb->cmn);
|
||||
if (ret >= 0)
|
||||
{
|
||||
sporadic = ptcb->cmn.sporadic;
|
||||
DEBUGASSERT(sporadic != NULL);
|
||||
|
||||
/* Save the sporadic scheduling parameters */
|
||||
|
||||
sporadic->hi_priority = param.sched_priority;
|
||||
sporadic->low_priority = param.sched_ss_low_priority;
|
||||
sporadic->max_repl = param.sched_ss_max_repl;
|
||||
sporadic->repl_period = repl_ticks;
|
||||
sporadic->budget = budget_ticks;
|
||||
|
||||
/* And start the first replenishment interval */
|
||||
|
||||
ret = sched_sporadic_start(&ptcb->cmn);
|
||||
}
|
||||
|
||||
/* Handle any failures */
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_join;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize the task control block */
|
||||
|
||||
ret = pthread_schedsetup(ptcb, priority, pthread_start, start_routine);
|
||||
ret = pthread_schedsetup(ptcb, param.sched_priority, pthread_start,
|
||||
start_routine);
|
||||
if (ret != OK)
|
||||
{
|
||||
errcode = EBUSY;
|
||||
|
||||
+5
-3
@@ -246,9 +246,11 @@ uint32_t sched_roundrobin_process(FAR struct tcb_s *tcb, uint32_t ticks,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
int sched_sporadic_start(FAR struct tcb_s *tcb);
|
||||
int sched_sporadic_stop(FAR struct tcb_s *tcb);
|
||||
int sched_sporadic_resume(FAR struct tcb_s *tcb);
|
||||
int sched_sporadic_initialize(FAR struct tcb_s *tcb);
|
||||
int sched_sporadic_start(FAR struct tcb_s *tcb);
|
||||
int sched_sporadic_stop(FAR struct tcb_s *tcb);
|
||||
int sched_sporadic_reset(FAR struct tcb_s *tcb);
|
||||
int sched_sporadic_resume(FAR struct tcb_s *tcb);
|
||||
uint32_t sched_sporadic_process(FAR struct tcb_s *tcb, uint32_t ticks,
|
||||
bool noswitches);
|
||||
void sched_sporadic_lowpriority(FAR struct tcb_s *tcb);
|
||||
|
||||
@@ -134,22 +134,35 @@ int sched_getparam (pid_t pid, FAR struct sched_param *param)
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
#endif
|
||||
/* Return the priority of the task */
|
||||
|
||||
param->sched_priority = (int)tcb->sched_priority;
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
/* Return parameters associated with SCHED_SPORADIC */
|
||||
if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
|
||||
{
|
||||
FAR struct sporadic_s *sporadic = tcb->sporadic;
|
||||
DEBUGASSERT(sporadic != NULL);
|
||||
|
||||
param->sched_ss_low_priority = (int)tcb->low_priority;
|
||||
#ifdef __REVISIT_REPLENISHMENTS
|
||||
param->sched_ss_max_repl = (int)tcb->max_repl;
|
||||
#else
|
||||
param->sched_ss_max_repl = 1;
|
||||
#endif
|
||||
/* Return parameters associated with SCHED_SPORADIC */
|
||||
|
||||
clock_ticks2time((int)tcb->repl_period, ¶m->sched_ss_repl_period);
|
||||
clock_ticks2time((int)tcb->budget, ¶m->sched_ss_init_budget);
|
||||
param->sched_ss_low_priority = (int)sporadic->low_priority;
|
||||
param->sched_ss_max_repl = (int)sporadic->max_repl;
|
||||
|
||||
clock_ticks2time((int)sporadic->repl_period, ¶m->sched_ss_repl_period);
|
||||
clock_ticks2time((int)sporadic->budget, ¶m->sched_ss_init_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
|
||||
}
|
||||
|
||||
|
||||
@@ -131,19 +131,35 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param)
|
||||
|
||||
if ((rtcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
|
||||
{
|
||||
FAR struct sporadic_s *sporadic;
|
||||
irqstate_t flags;
|
||||
int repl_ticks;
|
||||
int budget_ticks;
|
||||
|
||||
#ifdef __REVISIT_REPLENISHMENTS
|
||||
DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX);
|
||||
#endif
|
||||
if (param->sched_ss_max_repl < 1 ||
|
||||
param->sched_ss_max_repl > CONFIG_SCHED_SPORADIC_MAXREPL)
|
||||
{
|
||||
errcode = EINVAL;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Avoid zero/negative times */
|
||||
|
||||
if (repl_ticks < 1)
|
||||
{
|
||||
repl_ticks = 1;
|
||||
}
|
||||
|
||||
if (budget_ticks < 1)
|
||||
{
|
||||
budget_ticks = 1;
|
||||
}
|
||||
|
||||
/* The replenishment period must be greater than or equal to the
|
||||
* budget period.
|
||||
*/
|
||||
@@ -157,35 +173,37 @@ int sched_setparam(pid_t pid, FAR const struct sched_param *param)
|
||||
/* Stop/reset current sporadic scheduling */
|
||||
|
||||
flags = irqsave();
|
||||
DEBUGVERIFY(sched_sporadic_stop(tcb));
|
||||
ret = sched_sporadic_reset(tcb);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* Save the sporadic scheduling parameters and reset to the
|
||||
* beginning to the replenishment interval.
|
||||
*/
|
||||
|
||||
/* Save the sporadic scheduling parameters and reset to the beginning
|
||||
* to the replenishment interval.
|
||||
*/
|
||||
tcb->timeslice = budget_ticks;
|
||||
|
||||
tcb->timeslice = budget_ticks;
|
||||
tcb->hi_priority = param->sched_priority;
|
||||
tcb->low_priority = param->sched_ss_low_priority;
|
||||
#ifdef __REVISIT_REPLENISHMENTS
|
||||
tcb->max_repl = param->sched_ss_max_repl;
|
||||
#endif
|
||||
tcb->repl_period = repl_ticks;
|
||||
tcb->budget = budget_ticks;
|
||||
sporadic = rtcb->sporadic;
|
||||
DEBUGASSERT(sporadic != NULL);
|
||||
|
||||
/* And restart at the next replenishment interval */
|
||||
sporadic->hi_priority = param->sched_priority;
|
||||
sporadic->low_priority = param->sched_ss_low_priority;
|
||||
sporadic->max_repl = param->sched_ss_max_repl;
|
||||
sporadic->repl_period = repl_ticks;
|
||||
sporadic->budget = budget_ticks;
|
||||
|
||||
/* And restart at the next replenishment interval */
|
||||
|
||||
ret = sched_sporadic_start(tcb);
|
||||
}
|
||||
|
||||
/* Restore interrupts and handler errors */
|
||||
|
||||
DEBUGVERIFY(sched_sporadic_start(tcb));
|
||||
irqrestore(flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcb->hi_priority = 0;
|
||||
tcb->low_priority = 0;
|
||||
#ifdef __REVISIT_REPLENISHMENTS
|
||||
tcb->max_repl = 0;
|
||||
#endif
|
||||
tcb->repl_period = 0;
|
||||
tcb->budget = 0;
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_lock;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -87,6 +87,9 @@ int sched_setscheduler(pid_t pid, int policy,
|
||||
{
|
||||
FAR struct tcb_s *tcb;
|
||||
irqstate_t saved_state;
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
int errcode;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
/* Check for supported scheduling policy */
|
||||
@@ -175,49 +178,83 @@ int sched_setscheduler(pid_t pid, int policy,
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
case SCHED_SPORADIC:
|
||||
{
|
||||
FAR struct sporadic_s *sporadic;
|
||||
int repl_ticks;
|
||||
int budget_ticks;
|
||||
|
||||
#ifdef __REVISIT_REPLENISHMENTS
|
||||
DEBUGASSERT(param->sched_ss_max_repl <= UINT8_MAX);
|
||||
#endif
|
||||
if (param->sched_ss_max_repl < 1 ||
|
||||
param->sched_ss_max_repl > CONFIG_SCHED_SPORADIC_MAXREPL)
|
||||
{
|
||||
errcode = EINVAL;
|
||||
goto errout_with_irq;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Avoid zero/negative times */
|
||||
|
||||
if (repl_ticks < 1)
|
||||
{
|
||||
repl_ticks = 1;
|
||||
}
|
||||
|
||||
if (budget_ticks < 1)
|
||||
{
|
||||
budget_ticks = 1;
|
||||
}
|
||||
|
||||
/* The replenishment period must be greater than or equal to the
|
||||
* budget period.
|
||||
*/
|
||||
|
||||
if (repl_ticks < budget_ticks)
|
||||
{
|
||||
set_errno(EINVAL);
|
||||
irqrestore(saved_state);
|
||||
sched_unlock();
|
||||
return ERROR;
|
||||
errcode = EINVAL;
|
||||
goto errout_with_irq;
|
||||
}
|
||||
|
||||
/* Stop/reset current sporadic scheduling */
|
||||
/* Initialize/reset current sporadic scheduling */
|
||||
|
||||
DEBUGVERIFY(sched_sporadic_stop(tcb));
|
||||
if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
|
||||
{
|
||||
ret = sched_sporadic_reset(tcb);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = sched_sporadic_initialize(tcb);
|
||||
}
|
||||
|
||||
/* Save the sporadic scheduling parameters. */
|
||||
|
||||
tcb->flags |= TCB_FLAG_SCHED_SPORADIC;
|
||||
tcb->timeslice = budget_ticks;
|
||||
tcb->hi_priority = param->sched_priority;
|
||||
tcb->low_priority = param->sched_ss_low_priority;
|
||||
#ifdef __REVISIT_REPLENISHMENTS
|
||||
tcb->max_repl = param->sched_ss_max_repl;
|
||||
#endif
|
||||
tcb->repl_period = repl_ticks;
|
||||
tcb->budget = budget_ticks;
|
||||
if (ret >= 0)
|
||||
{
|
||||
tcb->flags |= TCB_FLAG_SCHED_SPORADIC;
|
||||
tcb->timeslice = budget_ticks;
|
||||
|
||||
/* And restart at the next replenishment interval */
|
||||
sporadic = tcb->sporadic;
|
||||
DEBUGASSERT(sporadic != NULL);
|
||||
|
||||
DEBUGVERIFY(sched_sporadic_start(tcb));
|
||||
sporadic->hi_priority = param->sched_priority;
|
||||
sporadic->low_priority = param->sched_ss_low_priority;
|
||||
sporadic->max_repl = param->sched_ss_max_repl;
|
||||
sporadic->repl_period = repl_ticks;
|
||||
sporadic->budget = budget_ticks;
|
||||
|
||||
/* And restart at the next replenishment interval */
|
||||
|
||||
ret = sched_sporadic_start(tcb);
|
||||
}
|
||||
|
||||
/* Handle errors */
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
errcode = -ret;
|
||||
goto errout_with_irq;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -236,4 +273,12 @@ int sched_setscheduler(pid_t pid, int policy,
|
||||
ret = sched_reprioritize(tcb, param->sched_priority);
|
||||
sched_unlock();
|
||||
return (ret >= 0) ? OK : ERROR;
|
||||
|
||||
#ifdef CONFIG_SCHED_SPORADIC
|
||||
errout_with_irq:
|
||||
set_errno(errcode);
|
||||
irqrestore(saved_state);
|
||||
sched_unlock();
|
||||
return ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
+598
-138
File diff suppressed because it is too large
Load Diff
@@ -76,7 +76,7 @@
|
||||
#if CONFIG_RR_INTERVAL > 0
|
||||
# define KEEP_ALIVE_TICKS MSEC2TICK(CONFIG_RR_INTERVAL)
|
||||
#else
|
||||
# define KEEP_ALIVE_TICKS MSEC2TICK(50)
|
||||
# define KEEP_ALIVE_TICKS MSEC2TICK(80)
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
|
||||
Reference in New Issue
Block a user