aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-07-16 20:20:52 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2012-07-16 20:20:52 -0400
commit1253e42eae22b6439ac9f3027d01740c95b8dcd6 (patch)
tree810946cbe2912b3876ddb3c403aa540749b7f0a2
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
New Feature: Arbitrary deadlines.
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.h1
-rw-r--r--include/litmus/rt_param.h1
-rw-r--r--litmus/jobs.c21
-rw-r--r--litmus/litmus.c25
-rw-r--r--litmus/rt_domain.c7
-rw-r--r--litmus/sched_pfair.c7
6 files changed, 45 insertions, 17 deletions
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h
index 0b071fd359f9..00b434f83c75 100644
--- a/include/litmus/litmus.h
+++ b/include/litmus/litmus.h
@@ -50,6 +50,7 @@ void litmus_exit_task(struct task_struct *tsk);
50#define get_exec_cost(t) (tsk_rt(t)->task_params.exec_cost) 50#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) 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) 52#define get_rt_period(t) (tsk_rt(t)->task_params.period)
53#define get_rt_rdeadline(t) (tsk_rt(t)->task_params.rdeadline)
53#define get_rt_phase(t) (tsk_rt(t)->task_params.phase) 54#define get_rt_phase(t) (tsk_rt(t)->task_params.phase)
54#define get_partition(t) (tsk_rt(t)->task_params.cpu) 55#define get_partition(t) (tsk_rt(t)->task_params.cpu)
55#define get_deadline(t) (tsk_rt(t)->job_params.deadline) 56#define get_deadline(t) (tsk_rt(t)->job_params.deadline)
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h
index d6d799174160..0ddd8c134533 100644
--- a/include/litmus/rt_param.h
+++ b/include/litmus/rt_param.h
@@ -36,6 +36,7 @@ typedef enum {
36struct rt_task { 36struct rt_task {
37 lt_t exec_cost; 37 lt_t exec_cost;
38 lt_t period; 38 lt_t period;
39 lt_t rdeadline;
39 lt_t phase; 40 lt_t phase;
40 unsigned int cpu; 41 unsigned int cpu;
41 task_class_t cls; 42 task_class_t cls;
diff --git a/litmus/jobs.c b/litmus/jobs.c
index 36e314625d86..44dd133a295a 100644
--- a/litmus/jobs.c
+++ b/litmus/jobs.c
@@ -6,12 +6,14 @@
6#include <litmus/litmus.h> 6#include <litmus/litmus.h>
7#include <litmus/jobs.h> 7#include <litmus/jobs.h>
8 8
9
9void prepare_for_next_period(struct task_struct *t) 10void prepare_for_next_period(struct task_struct *t)
10{ 11{
11 BUG_ON(!t); 12 BUG_ON(!t);
12 /* prepare next release */ 13 /* prepare next release */
13 t->rt_param.job_params.release = t->rt_param.job_params.deadline; 14 t->rt_param.job_params.release += get_rt_period(t);
14 t->rt_param.job_params.deadline += get_rt_period(t); 15 t->rt_param.job_params.deadline = t->rt_param.job_params.release
16 + get_rt_rdeadline(t);
15 t->rt_param.job_params.exec_time = 0; 17 t->rt_param.job_params.exec_time = 0;
16 /* update job sequence number */ 18 /* update job sequence number */
17 t->rt_param.job_params.job_no++; 19 t->rt_param.job_params.job_no++;
@@ -22,8 +24,19 @@ void prepare_for_next_period(struct task_struct *t)
22 24
23void release_at(struct task_struct *t, lt_t start) 25void release_at(struct task_struct *t, lt_t start)
24{ 26{
25 t->rt_param.job_params.deadline = start; 27 BUG_ON(!t);
26 prepare_for_next_period(t); 28
29 /* prepare next release */
30 t->rt_param.job_params.release = start;
31 t->rt_param.job_params.deadline = start + get_rt_rdeadline(t);
32 t->rt_param.job_params.exec_time = 0;
33
34 /* update job sequence number */
35 t->rt_param.job_params.job_no++;
36
37 /* don't confuse Linux */
38 t->rt.time_slice = 1;
39
27 set_rt_flags(t, RT_F_RUNNING); 40 set_rt_flags(t, RT_F_RUNNING);
28} 41}
29 42
diff --git a/litmus/litmus.c b/litmus/litmus.c
index 301390148d02..0ee0926f37d3 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.rdeadline == 0)
107 tp.rdeadline = 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 (tp.rdeadline < tp.exec_cost)
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 wcet greater than relative deadline\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,12 @@ 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_rdeadline(tsk) == 0 ||
325 get_exec_cost(tsk) > get_rt_period(tsk)) { 329 get_exec_cost(tsk) > get_rt_rdeadline(tsk)) {
326 TRACE_TASK(tsk, "litmus admit: invalid task parameters " 330 TRACE_TASK(tsk,
327 "(%lu, %lu)\n", 331 "litmus admit: invalid task parameters "
328 get_exec_cost(tsk), get_rt_period(tsk)); 332 "(e = %lu, p = %lu, d = %lu)\n",
333 get_exec_cost(tsk), get_rt_period(tsk), get_rt_rdeadline(tsk));
329 retval = -EINVAL; 334 retval = -EINVAL;
330 goto out; 335 goto out;
331 } 336 }
diff --git a/litmus/rt_domain.c b/litmus/rt_domain.c
index d405854cd39c..d4db03ab5f95 100644
--- a/litmus/rt_domain.c
+++ b/litmus/rt_domain.c
@@ -300,9 +300,10 @@ 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 to ready queue at %llu\n",
304 new->comm, new->pid, get_exec_cost(new), get_rt_period(new), 304 new->comm, new->pid,
305 get_release(new), litmus_clock()); 305 get_exec_cost(new), get_rt_period(new), get_rt_rdeadline(new),
306 get_release(new), litmus_clock());
306 307
307 BUG_ON(bheap_node_in_heap(tsk_rt(new)->heap_node)); 308 BUG_ON(bheap_node_in_heap(tsk_rt(new)->heap_node));
308 309
diff --git a/litmus/sched_pfair.c b/litmus/sched_pfair.c
index 16f1065bbdca..6cf764ec26d4 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_rdeadline(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.