diff options
| author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-07-16 20:20:52 -0400 |
|---|---|---|
| committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-08-01 02:40:25 -0400 |
| commit | b53c479a0f44b8990ce106622412a3bf54809944 (patch) | |
| tree | 07934618bf23661191b514a66bf8cd49d6369ece | |
| parent | a6d64b9717782170ba27c16b6df8191169d92fad (diff) | |
New Feature: Arbitrary deadlines.2012.2
Added support for arbitrary deadlines.
Constraint: Relative deadline must be >= exec cost.
Use: Set relative deadline in rt_task::rdeadline. Set value to 0
to default to implicit deadlines.
Limitations: PFAIR not supported by this patch. PFAIR updated to
reject tasks that do not have implicit deadlines.
| -rw-r--r-- | include/litmus/litmus.h | 13 | ||||
| -rw-r--r-- | include/litmus/rt_param.h | 1 | ||||
| -rw-r--r-- | litmus/jobs.c | 18 | ||||
| -rw-r--r-- | litmus/litmus.c | 27 | ||||
| -rw-r--r-- | litmus/rt_domain.c | 8 | ||||
| -rw-r--r-- | litmus/sched_pfair.c | 7 |
6 files changed, 51 insertions, 23 deletions
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h index aa56eeef7e7d..338245abd6ed 100644 --- a/include/litmus/litmus.h +++ b/include/litmus/litmus.h | |||
| @@ -47,18 +47,23 @@ void litmus_exit_task(struct task_struct *tsk); | |||
| 47 | /* Realtime utility macros */ | 47 | /* Realtime utility macros */ |
| 48 | #define get_rt_flags(t) (tsk_rt(t)->flags) | 48 | #define get_rt_flags(t) (tsk_rt(t)->flags) |
| 49 | #define set_rt_flags(t,f) (tsk_rt(t)->flags=(f)) | 49 | #define set_rt_flags(t,f) (tsk_rt(t)->flags=(f)) |
| 50 | #define is_priority_boosted(t) (tsk_rt(t)->priority_boosted) | ||
| 51 | #define get_boost_start(t) (tsk_rt(t)->boost_start_time) | ||
| 52 | |||
| 53 | /* task_params macros */ | ||
| 50 | #define get_exec_cost(t) (tsk_rt(t)->task_params.exec_cost) | 54 | #define get_exec_cost(t) (tsk_rt(t)->task_params.exec_cost) |
| 51 | #define get_exec_time(t) (tsk_rt(t)->job_params.exec_time) | ||
| 52 | #define get_rt_period(t) (tsk_rt(t)->task_params.period) | 55 | #define get_rt_period(t) (tsk_rt(t)->task_params.period) |
| 56 | #define get_rt_relative_deadline(t) (tsk_rt(t)->task_params.relative_deadline) | ||
| 53 | #define get_rt_phase(t) (tsk_rt(t)->task_params.phase) | 57 | #define get_rt_phase(t) (tsk_rt(t)->task_params.phase) |
| 54 | #define get_partition(t) (tsk_rt(t)->task_params.cpu) | 58 | #define get_partition(t) (tsk_rt(t)->task_params.cpu) |
| 55 | #define get_priority(t) (tsk_rt(t)->task_params.priority) | 59 | #define get_priority(t) (tsk_rt(t)->task_params.priority) |
| 60 | #define get_class(t) (tsk_rt(t)->task_params.cls) | ||
| 61 | |||
| 62 | /* job_param macros */ | ||
| 63 | #define get_exec_time(t) (tsk_rt(t)->job_params.exec_time) | ||
| 56 | #define get_deadline(t) (tsk_rt(t)->job_params.deadline) | 64 | #define get_deadline(t) (tsk_rt(t)->job_params.deadline) |
| 57 | #define get_release(t) (tsk_rt(t)->job_params.release) | 65 | #define get_release(t) (tsk_rt(t)->job_params.release) |
| 58 | #define get_class(t) (tsk_rt(t)->task_params.cls) | ||
| 59 | 66 | ||
| 60 | #define is_priority_boosted(t) (tsk_rt(t)->priority_boosted) | ||
| 61 | #define get_boost_start(t) (tsk_rt(t)->boost_start_time) | ||
| 62 | 67 | ||
| 63 | #define is_hrt(t) \ | 68 | #define is_hrt(t) \ |
| 64 | (tsk_rt(t)->task_params.cls == RT_CLASS_HARD) | 69 | (tsk_rt(t)->task_params.cls == RT_CLASS_HARD) |
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index c4669a276e6f..89ac0dda7d3d 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h | |||
| @@ -56,6 +56,7 @@ typedef enum { | |||
| 56 | struct rt_task { | 56 | struct rt_task { |
| 57 | lt_t exec_cost; | 57 | lt_t exec_cost; |
| 58 | lt_t period; | 58 | lt_t period; |
| 59 | lt_t relative_deadline; | ||
| 59 | lt_t phase; | 60 | lt_t phase; |
| 60 | unsigned int cpu; | 61 | unsigned int cpu; |
| 61 | unsigned int priority; | 62 | unsigned int priority; |
diff --git a/litmus/jobs.c b/litmus/jobs.c index 36e314625d86..bc8246572e54 100644 --- a/litmus/jobs.c +++ b/litmus/jobs.c | |||
| @@ -6,13 +6,13 @@ | |||
| 6 | #include <litmus/litmus.h> | 6 | #include <litmus/litmus.h> |
| 7 | #include <litmus/jobs.h> | 7 | #include <litmus/jobs.h> |
| 8 | 8 | ||
| 9 | void prepare_for_next_period(struct task_struct *t) | 9 | static inline void setup_release(struct task_struct *t, lt_t release) |
| 10 | { | 10 | { |
| 11 | BUG_ON(!t); | ||
| 12 | /* prepare next release */ | 11 | /* prepare next release */ |
| 13 | t->rt_param.job_params.release = t->rt_param.job_params.deadline; | 12 | t->rt_param.job_params.release = release; |
| 14 | t->rt_param.job_params.deadline += get_rt_period(t); | 13 | t->rt_param.job_params.deadline = release + get_rt_relative_deadline(t); |
| 15 | t->rt_param.job_params.exec_time = 0; | 14 | t->rt_param.job_params.exec_time = 0; |
| 15 | |||
| 16 | /* update job sequence number */ | 16 | /* update job sequence number */ |
| 17 | t->rt_param.job_params.job_no++; | 17 | t->rt_param.job_params.job_no++; |
| 18 | 18 | ||
| @@ -20,10 +20,16 @@ void prepare_for_next_period(struct task_struct *t) | |||
| 20 | t->rt.time_slice = 1; | 20 | t->rt.time_slice = 1; |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | void prepare_for_next_period(struct task_struct *t) | ||
| 24 | { | ||
| 25 | BUG_ON(!t); | ||
| 26 | setup_release(t, get_release(t) + get_rt_period(t)); | ||
| 27 | } | ||
| 28 | |||
| 23 | void release_at(struct task_struct *t, lt_t start) | 29 | void release_at(struct task_struct *t, lt_t start) |
| 24 | { | 30 | { |
| 25 | t->rt_param.job_params.deadline = start; | 31 | BUG_ON(!t); |
| 26 | prepare_for_next_period(t); | 32 | setup_release(t, start); |
| 27 | set_rt_flags(t, RT_F_RUNNING); | 33 | set_rt_flags(t, RT_F_RUNNING); |
| 28 | } | 34 | } |
| 29 | 35 | ||
diff --git a/litmus/litmus.c b/litmus/litmus.c index 301390148d02..81384327e850 100644 --- a/litmus/litmus.c +++ b/litmus/litmus.c | |||
| @@ -102,21 +102,25 @@ asmlinkage long sys_set_rt_task_param(pid_t pid, struct rt_task __user * param) | |||
| 102 | goto out_unlock; | 102 | goto out_unlock; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | /* set relative deadline to be implicit if left unspecified */ | ||
| 106 | if (tp.relative_deadline == 0) | ||
| 107 | tp.relative_deadline = tp.period; | ||
| 108 | |||
| 105 | if (tp.exec_cost <= 0) | 109 | if (tp.exec_cost <= 0) |
| 106 | goto out_unlock; | 110 | goto out_unlock; |
| 107 | if (tp.period <= 0) | 111 | if (tp.period <= 0) |
| 108 | goto out_unlock; | 112 | goto out_unlock; |
| 109 | if (!cpu_online(tp.cpu)) | 113 | if (!cpu_online(tp.cpu)) |
| 110 | goto out_unlock; | 114 | goto out_unlock; |
| 111 | if (tp.period < tp.exec_cost) | 115 | if (min(tp.relative_deadline, tp.period) < tp.exec_cost) /*density check*/ |
| 112 | { | 116 | { |
| 113 | printk(KERN_INFO "litmus: real-time task %d rejected " | 117 | printk(KERN_INFO "litmus: real-time task %d rejected " |
| 114 | "because wcet > period\n", pid); | 118 | "because task density > 1.0\n", pid); |
| 115 | goto out_unlock; | 119 | goto out_unlock; |
| 116 | } | 120 | } |
| 117 | if ( tp.cls != RT_CLASS_HARD && | 121 | if (tp.cls != RT_CLASS_HARD && |
| 118 | tp.cls != RT_CLASS_SOFT && | 122 | tp.cls != RT_CLASS_SOFT && |
| 119 | tp.cls != RT_CLASS_BEST_EFFORT) | 123 | tp.cls != RT_CLASS_BEST_EFFORT) |
| 120 | { | 124 | { |
| 121 | printk(KERN_INFO "litmus: real-time task %d rejected " | 125 | printk(KERN_INFO "litmus: real-time task %d rejected " |
| 122 | "because its class is invalid\n", pid); | 126 | "because its class is invalid\n", pid); |
| @@ -321,11 +325,14 @@ long litmus_admit_task(struct task_struct* tsk) | |||
| 321 | 325 | ||
| 322 | BUG_ON(is_realtime(tsk)); | 326 | BUG_ON(is_realtime(tsk)); |
| 323 | 327 | ||
| 324 | if (get_rt_period(tsk) == 0 || | 328 | if (get_rt_relative_deadline(tsk) == 0 || |
| 325 | get_exec_cost(tsk) > get_rt_period(tsk)) { | 329 | get_exec_cost(tsk) > |
| 326 | TRACE_TASK(tsk, "litmus admit: invalid task parameters " | 330 | min(get_rt_relative_deadline(tsk), get_rt_period(tsk)) ) { |
| 327 | "(%lu, %lu)\n", | 331 | TRACE_TASK(tsk, |
| 328 | get_exec_cost(tsk), get_rt_period(tsk)); | 332 | "litmus admit: invalid task parameters " |
| 333 | "(e = %lu, p = %lu, d = %lu)\n", | ||
| 334 | get_exec_cost(tsk), get_rt_period(tsk), | ||
| 335 | get_rt_relative_deadline(tsk)); | ||
| 329 | retval = -EINVAL; | 336 | retval = -EINVAL; |
| 330 | goto out; | 337 | goto out; |
| 331 | } | 338 | } |
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c index d405854cd39c..d0b796611bea 100644 --- a/litmus/rt_domain.c +++ b/litmus/rt_domain.c | |||
| @@ -300,9 +300,11 @@ void rt_domain_init(rt_domain_t *rt, | |||
| 300 | */ | 300 | */ |
| 301 | void __add_ready(rt_domain_t* rt, struct task_struct *new) | 301 | void __add_ready(rt_domain_t* rt, struct task_struct *new) |
| 302 | { | 302 | { |
| 303 | TRACE("rt: adding %s/%d (%llu, %llu) rel=%llu to ready queue at %llu\n", | 303 | TRACE("rt: adding %s/%d (%llu, %llu, %llu) rel=%llu " |
| 304 | new->comm, new->pid, get_exec_cost(new), get_rt_period(new), | 304 | "to ready queue at %llu\n", |
| 305 | get_release(new), litmus_clock()); | 305 | new->comm, new->pid, |
| 306 | get_exec_cost(new), get_rt_period(new), get_rt_relative_deadline(new), | ||
| 307 | get_release(new), litmus_clock()); | ||
| 306 | 308 | ||
| 307 | BUG_ON(bheap_node_in_heap(tsk_rt(new)->heap_node)); | 309 | BUG_ON(bheap_node_in_heap(tsk_rt(new)->heap_node)); |
| 308 | 310 | ||
diff --git a/litmus/sched_pfair.c b/litmus/sched_pfair.c index 16f1065bbdca..72c06a492ef9 100644 --- a/litmus/sched_pfair.c +++ b/litmus/sched_pfair.c | |||
| @@ -850,6 +850,13 @@ static long pfair_admit_task(struct task_struct* t) | |||
| 850 | cpu_cluster(pstate[task_cpu(t)])) | 850 | cpu_cluster(pstate[task_cpu(t)])) |
| 851 | return -EINVAL; | 851 | return -EINVAL; |
| 852 | 852 | ||
| 853 | if (get_rt_period(t) != get_rt_relative_deadline(t)) { | ||
| 854 | printk(KERN_INFO "%s: Admission rejected. " | ||
| 855 | "Only implicit deadlines are currently supported.\n", | ||
| 856 | litmus->plugin_name); | ||
| 857 | return -EINVAL; | ||
| 858 | } | ||
| 859 | |||
| 853 | /* Pfair is a tick-based method, so the time | 860 | /* Pfair is a tick-based method, so the time |
| 854 | * of interest is jiffies. Calculate tick-based | 861 | * of interest is jiffies. Calculate tick-based |
| 855 | * times for everything. | 862 | * times for everything. |
