From 06b23f7b33c61cf1f03acb2d19ddf5dc6c57a810 Mon Sep 17 00:00:00 2001 From: Andrea Bastoni Date: Tue, 21 Sep 2010 22:22:10 -0400 Subject: 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. --- include/litmus/rt_param.h | 64 ++++++++++++++++++++++++++++++----------------- 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) } #define lt_before_eq(a, b) lt_after_eq(b, a) -#define NR_CPUS_EDF_FM 2 -#define NR_CPUS_SEMI NR_CPUS_EDF_FM - /* different types of clients */ typedef enum { RT_CLASS_HARD, @@ -36,6 +33,31 @@ typedef enum { PRECISE_ENFORCEMENT /* NOT IMPLEMENTED - enforced with hrtimers */ } budget_policy_t; + +/* Parameters for EDF-Fm scheduling algorithm. + * Each task may be fixed or migratory. Migratory tasks may + * migrate on 2 (contiguous) CPU only. NR_CPUS_EDF_FM = 2. + */ +#define NR_CPUS_EDF_FM 2 + +struct edffm_params { + /* EDF-fm where can a migratory task execute? */ + unsigned int cpus[NR_CPUS_EDF_FM]; + /* how many cpus are used by this task? + * fixed = 0, migratory = (NR_CPUS_EDF_FM - 1) + * Efficient way to allow writing cpus[nr_cpus]. + */ + unsigned int nr_cpus; + /* Fraction of this task exec_cost that each CPU should handle. + * We keep the fraction divided in num/denom : a matrix of + * (NR_CPUS_EDF_FM rows) x (2 columns). + * The first column is the numerator of the fraction. + * The second column is the denominator. + * In EDF-fm this is a 2*2 matrix + */ + lt_t fraction[2][NR_CPUS_EDF_FM]; +}; + struct rt_task { lt_t exec_cost; lt_t period; @@ -43,21 +65,12 @@ struct rt_task { unsigned int cpu; task_class_t cls; budget_policy_t budget_policy; /* ignored by pfair */ - /* EDF-fm where can a migrat task execute? */ - unsigned int cpus[NR_CPUS_SEMI]; - /* how many cpus are used by this task? fixed = 0, migrat = multi - * nr_cpus = (number of cpu where the task can be migrated) - 1 - * so that one can use: cpus[nr_cpus] - */ - unsigned int nr_cpus; - /* EDF-fm migrating tasks, fraction of this task exec_cost - * that the processors should handle. - * We keep the fraction divided in num/denom : a matrix of - * NR_CPUS_SEMI rows * 2 columns; first column is the numerator - * of the fraction, second column is the denominator - * (in EDF-fm this is a 2*2 matrix) - */ - lt_t fraction[2][NR_CPUS_SEMI]; + + /* parameters used by the semi-partitioned algorithms */ + union { + /* EDF-Fm; defined in sched_edf_fm.c */ + struct edffm_params fm; + } semi_part; }; /* The definition of the data that is shared between the kernel and real-time @@ -108,11 +121,6 @@ struct rt_job { * Increase this sequence number when a job is released. */ unsigned int job_no; - - /* EDF-fm: number of jobs handled by this cpu - * (to determine next cpu for a migrating task) - */ - unsigned int cpu_job_no[NR_CPUS_SEMI]; }; struct pfair_param; @@ -207,6 +215,16 @@ struct rt_param { /* Pointer to the page shared between userspace and kernel. */ struct control_page * ctrl_page; + + /* runtime info for the semi-part plugins */ + union { + struct { + /* EDF-fm: number of jobs handled by this cpu + * (to determine next cpu for a migrating task) + */ + unsigned int cpu_job_no[NR_CPUS_EDF_FM]; + } fm; + } semi_part; }; /* 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); #define task_edf(task) remote_edf(get_partition(task)) #define task_edffm(task) remote_edffm(get_partition(task)) +#define edffm_params(t) (t->rt_param.task_params.semi_part.fm) + /* Is the task a migratory task? */ -#define is_migrat_task(task) (tsk_rt(task)->task_params.nr_cpus) +#define is_migrat_task(task) (edffm_params(task).nr_cpus) /* t is on the wrong CPU (it should be requeued properly) */ #define wrong_cpu(t) is_migrat_task((t)) && task_cpu((t)) != get_partition((t)) /* Get next CPU */ #define migrat_next_cpu(t) \ - ((tsk_rt(t)->task_params.cpu == tsk_rt(t)->task_params.cpus[0]) ? \ - tsk_rt(t)->task_params.cpus[1] : \ - tsk_rt(t)->task_params.cpus[0]) + ((tsk_rt(t)->task_params.cpu == edffm_params(t).cpus[0]) ? \ + edffm_params(t).cpus[1] : \ + edffm_params(t).cpus[0]) /* Get current cpu */ #define migrat_cur_cpu(t) \ - ((tsk_rt(t)->task_params.cpu == tsk_rt(t)->task_params.cpus[0]) ? \ - tsk_rt(t)->task_params.cpus[0] : \ - tsk_rt(t)->task_params.cpus[1]) + ((tsk_rt(t)->task_params.cpu == edffm_params(t).cpus[0]) ? \ + edffm_params(t).cpus[0] : \ + edffm_params(t).cpus[1]) /* Manipulate share for current cpu */ #define cur_cpu_fract_num(t) \ - ((tsk_rt(t)->task_params.cpu == tsk_rt(t)->task_params.cpus[0]) ? \ - tsk_rt(t)->task_params.fraction[0][0] : \ - tsk_rt(t)->task_params.fraction[0][1]) + ((tsk_rt(t)->task_params.cpu == edffm_params(t).cpus[0]) ? \ + edffm_params(t).fraction[0][0] : \ + edffm_params(t).fraction[0][1]) #define cur_cpu_fract_den(t) \ - ((tsk_rt(t)->task_params.cpu == tsk_rt(t)->task_params.cpus[0]) ? \ - tsk_rt(t)->task_params.fraction[1][0] : \ - tsk_rt(t)->task_params.fraction[1][1]) + ((tsk_rt(t)->task_params.cpu == edffm_params(t).cpus[0]) ? \ + edffm_params(t).fraction[1][0] : \ + edffm_params(t).fraction[1][1]) /* Get job number for current cpu */ #define cur_cpu_job_no(t) \ - ((tsk_rt(t)->task_params.cpu == tsk_rt(t)->task_params.cpus[0]) ? \ - tsk_rt(t)->job_params.cpu_job_no[0] : \ - tsk_rt(t)->job_params.cpu_job_no[1]) + ((tsk_rt(t)->task_params.cpu == edffm_params(t).cpus[0]) ? \ + tsk_rt(t)->semi_part.fm.cpu_job_no[0] : \ + tsk_rt(t)->semi_part.fm.cpu_job_no[1]) /* What is the current cpu position in the array? */ #define edffm_cpu_pos(cpu,t) \ - ((cpu == tsk_rt(t)->task_params.cpus[0]) ? \ + ((cpu == edffm_params(t).cpus[0]) ? \ 0 : 1) /* @@ -71,14 +73,14 @@ DEFINE_PER_CPU(edffm_domain_t, edffm_domains); */ int edffm_higher_prio(struct task_struct* first, struct task_struct* second) { - if ((first && tsk_rt(first)->task_params.nr_cpus) || - (second && tsk_rt(second)->task_params.nr_cpus)) { - if ((first && tsk_rt(first)->task_params.nr_cpus) && - (second && tsk_rt(second)->task_params.nr_cpus)) + if ((first && edffm_params(first).nr_cpus) || + (second && edffm_params(second).nr_cpus)) { + if ((first && edffm_params(first).nr_cpus) && + (second && edffm_params(second).nr_cpus)) /* both are migrating */ return edf_higher_prio(first, second); - if (first && tsk_rt(first)->task_params.nr_cpus) + if (first && edffm_params(first).nr_cpus) /* first is migrating */ return 1; else @@ -257,7 +259,7 @@ static void update_job_counter(struct task_struct *t) /* Which CPU counter should be incremented? */ cpu_pos = edffm_cpu_pos(t->rt_param.task_params.cpu, t); - t->rt_param.job_params.cpu_job_no[cpu_pos]++; + t->rt_param.semi_part.fm.cpu_job_no[cpu_pos]++; TRACE_TASK(t, "job_no = %d, cpu_job_no(pos %d) = %d, cpu %d\n", 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) if ((t->rt_param.job_params.job_no) == (((lt_t) cur_cpu_job_no(t) * cur_cpu_fract_den(t)) / cur_cpu_fract_num(t))) - return tsk_rt(t)->task_params.cpus[0]; + return edffm_params(t).cpus[0]; - return tsk_rt(t)->task_params.cpus[1]; + return edffm_params(t).cpus[1]; } /* If needed (the share for task t on this CPU is exhausted), updates -- cgit v1.2.2