aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-09-21 22:22:10 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-09-22 15:18:53 -0400
commit06b23f7b33c61cf1f03acb2d19ddf5dc6c57a810 (patch)
tree7154b56b91b08387835089604709ec34d9b7d21c
parent844cba1fd1189a755e60317a3f2b4403e7908b5b (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.h64
-rw-r--r--litmus/sched_edf_fm.c52
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 */
27typedef enum { 24typedef 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
43struct 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
39struct rt_task { 61struct 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
118struct pfair_param; 126struct 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 */
72int edffm_higher_prio(struct task_struct* first, struct task_struct* second) 74int 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