diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-09-21 22:22:10 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-09-22 15:18:53 -0400 |
commit | 06b23f7b33c61cf1f03acb2d19ddf5dc6c57a810 (patch) | |
tree | 7154b56b91b08387835089604709ec34d9b7d21c | |
parent | 844cba1fd1189a755e60317a3f2b4403e7908b5b (diff) |
Remove EDF-Fm specific parameters from rt_param.h
Move parameters specific to EDF-Fm plugin only inside a dedicated data
structure. Use union within rt_task to merge also the other semi-part
plugins.
-rw-r--r-- | include/litmus/rt_param.h | 64 | ||||
-rw-r--r-- | litmus/sched_edf_fm.c | 52 |
2 files changed, 68 insertions, 48 deletions
diff --git a/include/litmus/rt_param.h b/include/litmus/rt_param.h index 1c63b006f50e..90685e93ad21 100644 --- a/include/litmus/rt_param.h +++ b/include/litmus/rt_param.h | |||
@@ -20,9 +20,6 @@ static inline int lt_after_eq(lt_t a, lt_t b) | |||
20 | } | 20 | } |
21 | #define lt_before_eq(a, b) lt_after_eq(b, a) | 21 | #define lt_before_eq(a, b) lt_after_eq(b, a) |
22 | 22 | ||
23 | #define NR_CPUS_EDF_FM 2 | ||
24 | #define NR_CPUS_SEMI NR_CPUS_EDF_FM | ||
25 | |||
26 | /* different types of clients */ | 23 | /* different types of clients */ |
27 | typedef enum { | 24 | typedef enum { |
28 | RT_CLASS_HARD, | 25 | RT_CLASS_HARD, |
@@ -36,6 +33,31 @@ typedef enum { | |||
36 | PRECISE_ENFORCEMENT /* NOT IMPLEMENTED - enforced with hrtimers */ | 33 | PRECISE_ENFORCEMENT /* NOT IMPLEMENTED - enforced with hrtimers */ |
37 | } budget_policy_t; | 34 | } budget_policy_t; |
38 | 35 | ||
36 | |||
37 | /* Parameters for EDF-Fm scheduling algorithm. | ||
38 | * Each task may be fixed or migratory. Migratory tasks may | ||
39 | * migrate on 2 (contiguous) CPU only. NR_CPUS_EDF_FM = 2. | ||
40 | */ | ||
41 | #define NR_CPUS_EDF_FM 2 | ||
42 | |||
43 | struct edffm_params { | ||
44 | /* EDF-fm where can a migratory task execute? */ | ||
45 | unsigned int cpus[NR_CPUS_EDF_FM]; | ||
46 | /* how many cpus are used by this task? | ||
47 | * fixed = 0, migratory = (NR_CPUS_EDF_FM - 1) | ||
48 | * Efficient way to allow writing cpus[nr_cpus]. | ||
49 | */ | ||
50 | unsigned int nr_cpus; | ||
51 | /* Fraction of this task exec_cost that each CPU should handle. | ||
52 | * We keep the fraction divided in num/denom : a matrix of | ||
53 | * (NR_CPUS_EDF_FM rows) x (2 columns). | ||
54 | * The first column is the numerator of the fraction. | ||
55 | * The second column is the denominator. | ||
56 | * In EDF-fm this is a 2*2 matrix | ||
57 | */ | ||
58 | lt_t fraction[2][NR_CPUS_EDF_FM]; | ||
59 | }; | ||
60 | |||
39 | struct rt_task { | 61 | struct rt_task { |
40 | lt_t exec_cost; | 62 | lt_t exec_cost; |
41 | lt_t period; | 63 | lt_t period; |
@@ -43,21 +65,12 @@ struct rt_task { | |||
43 | unsigned int cpu; | 65 | unsigned int cpu; |
44 | task_class_t cls; | 66 | task_class_t cls; |
45 | budget_policy_t budget_policy; /* ignored by pfair */ | 67 | budget_policy_t budget_policy; /* ignored by pfair */ |
46 | /* EDF-fm where can a migrat task execute? */ | 68 | |
47 | unsigned int cpus[NR_CPUS_SEMI]; | 69 | /* parameters used by the semi-partitioned algorithms */ |
48 | /* how many cpus are used by this task? fixed = 0, migrat = multi | 70 | union { |
49 | * nr_cpus = (number of cpu where the task can be migrated) - 1 | 71 | /* EDF-Fm; defined in sched_edf_fm.c */ |
50 | * so that one can use: cpus[nr_cpus] | 72 | struct edffm_params fm; |
51 | */ | 73 | } semi_part; |
52 | unsigned int nr_cpus; | ||
53 | /* EDF-fm migrating tasks, fraction of this task exec_cost | ||
54 | * that the processors should handle. | ||
55 | * We keep the fraction divided in num/denom : a matrix of | ||
56 | * NR_CPUS_SEMI rows * 2 columns; first column is the numerator | ||
57 | * of the fraction, second column is the denominator | ||
58 | * (in EDF-fm this is a 2*2 matrix) | ||
59 | */ | ||
60 | lt_t fraction[2][NR_CPUS_SEMI]; | ||
61 | }; | 74 | }; |
62 | 75 | ||
63 | /* The definition of the data that is shared between the kernel and real-time | 76 | /* The definition of the data that is shared between the kernel and real-time |
@@ -108,11 +121,6 @@ struct rt_job { | |||
108 | * Increase this sequence number when a job is released. | 121 | * Increase this sequence number when a job is released. |
109 | */ | 122 | */ |
110 | unsigned int job_no; | 123 | unsigned int job_no; |
111 | |||
112 | /* EDF-fm: number of jobs handled by this cpu | ||
113 | * (to determine next cpu for a migrating task) | ||
114 | */ | ||
115 | unsigned int cpu_job_no[NR_CPUS_SEMI]; | ||
116 | }; | 124 | }; |
117 | 125 | ||
118 | struct pfair_param; | 126 | struct pfair_param; |
@@ -207,6 +215,16 @@ struct rt_param { | |||
207 | 215 | ||
208 | /* Pointer to the page shared between userspace and kernel. */ | 216 | /* Pointer to the page shared between userspace and kernel. */ |
209 | struct control_page * ctrl_page; | 217 | struct control_page * ctrl_page; |
218 | |||
219 | /* runtime info for the semi-part plugins */ | ||
220 | union { | ||
221 | struct { | ||
222 | /* EDF-fm: number of jobs handled by this cpu | ||
223 | * (to determine next cpu for a migrating task) | ||
224 | */ | ||
225 | unsigned int cpu_job_no[NR_CPUS_EDF_FM]; | ||
226 | } fm; | ||
227 | } semi_part; | ||
210 | }; | 228 | }; |
211 | 229 | ||
212 | /* Possible RT flags */ | 230 | /* Possible RT flags */ |
diff --git a/litmus/sched_edf_fm.c b/litmus/sched_edf_fm.c index 70c5d289288f..e14f8588c7a4 100644 --- a/litmus/sched_edf_fm.c +++ b/litmus/sched_edf_fm.c | |||
@@ -32,37 +32,39 @@ DEFINE_PER_CPU(edffm_domain_t, edffm_domains); | |||
32 | #define task_edf(task) remote_edf(get_partition(task)) | 32 | #define task_edf(task) remote_edf(get_partition(task)) |
33 | #define task_edffm(task) remote_edffm(get_partition(task)) | 33 | #define task_edffm(task) remote_edffm(get_partition(task)) |
34 | 34 | ||
35 | #define edffm_params(t) (t->rt_param.task_params.semi_part.fm) | ||
36 | |||
35 | /* Is the task a migratory task? */ | 37 | /* Is the task a migratory task? */ |
36 | #define is_migrat_task(task) (tsk_rt(task)->task_params.nr_cpus) | 38 | #define is_migrat_task(task) (edffm_params(task).nr_cpus) |
37 | /* t is on the wrong CPU (it should be requeued properly) */ | 39 | /* t is on the wrong CPU (it should be requeued properly) */ |
38 | #define wrong_cpu(t) is_migrat_task((t)) && task_cpu((t)) != get_partition((t)) | 40 | #define wrong_cpu(t) is_migrat_task((t)) && task_cpu((t)) != get_partition((t)) |
39 | /* Get next CPU */ | 41 | /* Get next CPU */ |
40 | #define migrat_next_cpu(t) \ | 42 | #define migrat_next_cpu(t) \ |
41 | ((tsk_rt(t)->task_params.cpu == tsk_rt(t)->task_params.cpus[0]) ? \ | 43 | ((tsk_rt(t)->task_params.cpu == edffm_params(t).cpus[0]) ? \ |
42 | tsk_rt(t)->task_params.cpus[1] : \ | 44 | edffm_params(t).cpus[1] : \ |
43 | tsk_rt(t)->task_params.cpus[0]) | 45 | edffm_params(t).cpus[0]) |
44 | /* Get current cpu */ | 46 | /* Get current cpu */ |
45 | #define migrat_cur_cpu(t) \ | 47 | #define migrat_cur_cpu(t) \ |
46 | ((tsk_rt(t)->task_params.cpu == tsk_rt(t)->task_params.cpus[0]) ? \ | 48 | ((tsk_rt(t)->task_params.cpu == edffm_params(t).cpus[0]) ? \ |
47 | tsk_rt(t)->task_params.cpus[0] : \ | 49 | edffm_params(t).cpus[0] : \ |
48 | tsk_rt(t)->task_params.cpus[1]) | 50 | edffm_params(t).cpus[1]) |
49 | /* Manipulate share for current cpu */ | 51 | /* Manipulate share for current cpu */ |
50 | #define cur_cpu_fract_num(t) \ | 52 | #define cur_cpu_fract_num(t) \ |
51 | ((tsk_rt(t)->task_params.cpu == tsk_rt(t)->task_params.cpus[0]) ? \ | 53 | ((tsk_rt(t)->task_params.cpu == edffm_params(t).cpus[0]) ? \ |
52 | tsk_rt(t)->task_params.fraction[0][0] : \ | 54 | edffm_params(t).fraction[0][0] : \ |
53 | tsk_rt(t)->task_params.fraction[0][1]) | 55 | edffm_params(t).fraction[0][1]) |
54 | #define cur_cpu_fract_den(t) \ | 56 | #define cur_cpu_fract_den(t) \ |
55 | ((tsk_rt(t)->task_params.cpu == tsk_rt(t)->task_params.cpus[0]) ? \ | 57 | ((tsk_rt(t)->task_params.cpu == edffm_params(t).cpus[0]) ? \ |
56 | tsk_rt(t)->task_params.fraction[1][0] : \ | 58 | edffm_params(t).fraction[1][0] : \ |
57 | tsk_rt(t)->task_params.fraction[1][1]) | 59 | edffm_params(t).fraction[1][1]) |
58 | /* Get job number for current cpu */ | 60 | /* Get job number for current cpu */ |
59 | #define cur_cpu_job_no(t) \ | 61 | #define cur_cpu_job_no(t) \ |
60 | ((tsk_rt(t)->task_params.cpu == tsk_rt(t)->task_params.cpus[0]) ? \ | 62 | ((tsk_rt(t)->task_params.cpu == edffm_params(t).cpus[0]) ? \ |
61 | tsk_rt(t)->job_params.cpu_job_no[0] : \ | 63 | tsk_rt(t)->semi_part.fm.cpu_job_no[0] : \ |
62 | tsk_rt(t)->job_params.cpu_job_no[1]) | 64 | tsk_rt(t)->semi_part.fm.cpu_job_no[1]) |
63 | /* What is the current cpu position in the array? */ | 65 | /* What is the current cpu position in the array? */ |
64 | #define edffm_cpu_pos(cpu,t) \ | 66 | #define edffm_cpu_pos(cpu,t) \ |
65 | ((cpu == tsk_rt(t)->task_params.cpus[0]) ? \ | 67 | ((cpu == edffm_params(t).cpus[0]) ? \ |
66 | 0 : 1) | 68 | 0 : 1) |
67 | 69 | ||
68 | /* | 70 | /* |
@@ -71,14 +73,14 @@ DEFINE_PER_CPU(edffm_domain_t, edffm_domains); | |||
71 | */ | 73 | */ |
72 | int edffm_higher_prio(struct task_struct* first, struct task_struct* second) | 74 | int edffm_higher_prio(struct task_struct* first, struct task_struct* second) |
73 | { | 75 | { |
74 | if ((first && tsk_rt(first)->task_params.nr_cpus) || | 76 | if ((first && edffm_params(first).nr_cpus) || |
75 | (second && tsk_rt(second)->task_params.nr_cpus)) { | 77 | (second && edffm_params(second).nr_cpus)) { |
76 | if ((first && tsk_rt(first)->task_params.nr_cpus) && | 78 | if ((first && edffm_params(first).nr_cpus) && |
77 | (second && tsk_rt(second)->task_params.nr_cpus)) | 79 | (second && edffm_params(second).nr_cpus)) |
78 | /* both are migrating */ | 80 | /* both are migrating */ |
79 | return edf_higher_prio(first, second); | 81 | return edf_higher_prio(first, second); |
80 | 82 | ||
81 | if (first && tsk_rt(first)->task_params.nr_cpus) | 83 | if (first && edffm_params(first).nr_cpus) |
82 | /* first is migrating */ | 84 | /* first is migrating */ |
83 | return 1; | 85 | return 1; |
84 | else | 86 | else |
@@ -257,7 +259,7 @@ static void update_job_counter(struct task_struct *t) | |||
257 | 259 | ||
258 | /* Which CPU counter should be incremented? */ | 260 | /* Which CPU counter should be incremented? */ |
259 | cpu_pos = edffm_cpu_pos(t->rt_param.task_params.cpu, t); | 261 | cpu_pos = edffm_cpu_pos(t->rt_param.task_params.cpu, t); |
260 | t->rt_param.job_params.cpu_job_no[cpu_pos]++; | 262 | t->rt_param.semi_part.fm.cpu_job_no[cpu_pos]++; |
261 | 263 | ||
262 | TRACE_TASK(t, "job_no = %d, cpu_job_no(pos %d) = %d, cpu %d\n", | 264 | TRACE_TASK(t, "job_no = %d, cpu_job_no(pos %d) = %d, cpu %d\n", |
263 | t->rt_param.job_params.job_no, cpu_pos, cur_cpu_job_no(t), | 265 | t->rt_param.job_params.job_no, cpu_pos, cur_cpu_job_no(t), |
@@ -272,9 +274,9 @@ static int next_cpu_for_job(struct task_struct *t) | |||
272 | if ((t->rt_param.job_params.job_no) == | 274 | if ((t->rt_param.job_params.job_no) == |
273 | (((lt_t) cur_cpu_job_no(t) * cur_cpu_fract_den(t)) / | 275 | (((lt_t) cur_cpu_job_no(t) * cur_cpu_fract_den(t)) / |
274 | cur_cpu_fract_num(t))) | 276 | cur_cpu_fract_num(t))) |
275 | return tsk_rt(t)->task_params.cpus[0]; | 277 | return edffm_params(t).cpus[0]; |
276 | 278 | ||
277 | return tsk_rt(t)->task_params.cpus[1]; | 279 | return edffm_params(t).cpus[1]; |
278 | } | 280 | } |
279 | 281 | ||
280 | /* If needed (the share for task t on this CPU is exhausted), updates | 282 | /* If needed (the share for task t on this CPU is exhausted), updates |