aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-07-16 20:20:52 -0400
committerBjoern Brandenburg <bbb@mpi-sws.org>2012-08-01 02:40:25 -0400
commitb53c479a0f44b8990ce106622412a3bf54809944 (patch)
tree07934618bf23661191b514a66bf8cd49d6369ece
parenta6d64b9717782170ba27c16b6df8191169d92fad (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.h13
-rw-r--r--include/litmus/rt_param.h1
-rw-r--r--litmus/jobs.c18
-rw-r--r--litmus/litmus.c27
-rw-r--r--litmus/rt_domain.c8
-rw-r--r--litmus/sched_pfair.c7
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 {
56struct rt_task { 56struct 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
9void prepare_for_next_period(struct task_struct *t) 9static 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
23void 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
23void release_at(struct task_struct *t, lt_t start) 29void 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 */
301void __add_ready(rt_domain_t* rt, struct task_struct *new) 301void __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.