diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-09-27 20:15:32 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-09-27 20:36:04 -0400 |
commit | 23a00b911b968c6290251913ecc34171836b4d32 (patch) | |
tree | f6c8289054d2961902931e89bdc11ccc01bc3a73 /litmus/ce_domain.c | |
parent | f21e1d0ef90c2e88ae6a563afc31ea601ed968c7 (diff) | |
parent | 609c45f71b7a2405230fd2f8436837d6389ec599 (diff) |
Merged with ce domains
Diffstat (limited to 'litmus/ce_domain.c')
-rw-r--r-- | litmus/ce_domain.c | 105 |
1 files changed, 31 insertions, 74 deletions
diff --git a/litmus/ce_domain.c b/litmus/ce_domain.c index 5b4fd1cb438..ac6cc14d44f 100644 --- a/litmus/ce_domain.c +++ b/litmus/ce_domain.c | |||
@@ -6,7 +6,9 @@ | |||
6 | #include <litmus/debug_trace.h> | 6 | #include <litmus/debug_trace.h> |
7 | #include <litmus/rt_param.h> | 7 | #include <litmus/rt_param.h> |
8 | #include <litmus/domain.h> | 8 | #include <litmus/domain.h> |
9 | #include <litmus/event_group.h> | ||
9 | #include <litmus/sched_mc.h> | 10 | #include <litmus/sched_mc.h> |
11 | #include <litmus/ce_domain.h> | ||
10 | 12 | ||
11 | /* | 13 | /* |
12 | * Called for: | 14 | * Called for: |
@@ -18,50 +20,26 @@ void ce_requeue(domain_t *dom, struct task_struct *ts) | |||
18 | { | 20 | { |
19 | const struct ce_dom_data *ce_data = dom->data; | 21 | const struct ce_dom_data *ce_data = dom->data; |
20 | const int idx = tsk_mc_data(ts)->mc_task.lvl_a_id; | 22 | const int idx = tsk_mc_data(ts)->mc_task.lvl_a_id; |
21 | const struct ce_dom_pid_entry *pid_entry = | 23 | const unsigned int just_finished = tsk_rt(ts)->job_params.job_no; |
22 | &ce_data->pid_entries[idx]; | 24 | const unsigned int expected_job = |
23 | const int just_finished = tsk_rt(ts)->job_params.job_no; | 25 | mc_ce_get_expected_job(ce_data->cpu, idx); |
24 | const int expected_job = pid_entry->expected_job; | ||
25 | const int asleep = RT_F_SLEEP == get_rt_flags(ts); | 26 | const int asleep = RT_F_SLEEP == get_rt_flags(ts); |
26 | 27 | ||
27 | TRACE_TASK(ts, "entered ce_requeue. asleep: %d just_finished: %4d " | 28 | TRACE_MC_TASK(ts, "entered ce_requeue. asleep: %d just_finished: %3u " |
28 | "expected_job: %4d\n", | 29 | "expected_job: %3u", |
29 | asleep, just_finished, expected_job); | 30 | asleep, just_finished, expected_job); |
30 | 31 | ||
31 | /* When coming from job completion, the task will be asleep. */ | 32 | /* When coming from job completion, the task will be asleep. */ |
32 | if (asleep && just_finished < expected_job) { | 33 | if (asleep && just_finished < expected_job) { |
33 | /* this job is running behind, so don't put it to sleep */ | 34 | TRACE_MC_TASK(ts, "appears behind"); |
34 | set_rt_flags(ts, RT_F_RUNNING); | ||
35 | TRACE_TASK(ts, "appears behind, setting it to running again\n"); | ||
36 | } else if (asleep && expected_job < just_finished) { | 35 | } else if (asleep && expected_job < just_finished) { |
37 | printk(KERN_CRIT "job %d completed in expected job %d which " | 36 | TRACE_MC_TASK(ts, "job %u completed in expected job %u which " |
38 | "seems too early\n", just_finished, | 37 | "seems too early", just_finished, |
39 | expected_job); | 38 | expected_job); |
40 | BUG(); | ||
41 | } | 39 | } |
42 | } | 40 | } |
43 | 41 | ||
44 | /* | 42 | /* |
45 | * Called when a task exits the system. | ||
46 | */ | ||
47 | void ce_exit(domain_t *dom, struct task_struct *ts) | ||
48 | { | ||
49 | struct ce_dom_data *ce_data = dom->data; | ||
50 | const int lvl_a_id = tsk_mc_data(ts)->mc_task.lvl_a_id; | ||
51 | struct pid *pid; | ||
52 | |||
53 | BUG_ON(task_cpu(ts) != get_partition(ts)); | ||
54 | BUG_ON(CRIT_LEVEL_A != tsk_mc_crit(ts)); | ||
55 | BUG_ON(lvl_a_id >= ce_data->num_pid_entries); | ||
56 | pid = ce_data->pid_entries[lvl_a_id].pid; | ||
57 | BUG_ON(!pid); | ||
58 | put_pid(pid); | ||
59 | ce_data->pid_entries[lvl_a_id].pid = NULL; | ||
60 | if (ce_data->should_schedule == ts) | ||
61 | ce_data->should_schedule = NULL; | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * ce_take_ready and ce_peek_ready | 43 | * ce_take_ready and ce_peek_ready |
66 | */ | 44 | */ |
67 | struct task_struct* ce_peek_and_take_ready(domain_t *dom) | 45 | struct task_struct* ce_peek_and_take_ready(domain_t *dom) |
@@ -71,57 +49,36 @@ struct task_struct* ce_peek_and_take_ready(domain_t *dom) | |||
71 | const int exists = NULL != ce_data->should_schedule; | 49 | const int exists = NULL != ce_data->should_schedule; |
72 | const int blocked = exists && !is_running(ce_data->should_schedule); | 50 | const int blocked = exists && !is_running(ce_data->should_schedule); |
73 | 51 | ||
74 | /* Return the task we should schedule if it is not blocked. If it is | 52 | /* Return the task we should schedule if it is not blocked or sleeping. */ |
75 | * asleep, return it anyway, because the MC-scheduler might as about | ||
76 | * ghost jobs. | ||
77 | */ | ||
78 | if (exists && !blocked) | 53 | if (exists && !blocked) |
79 | ret = ce_data->should_schedule; | 54 | ret = ce_data->should_schedule; |
80 | return ret; | 55 | return ret; |
81 | } | 56 | } |
82 | 57 | ||
83 | int ce_higher_prio(domain_t *dom, struct task_struct *_a, | 58 | int ce_higher_prio(struct task_struct *_a, struct task_struct *_b) |
84 | struct task_struct *_b) | ||
85 | { | 59 | { |
86 | const struct task_struct *a = _a; | 60 | const struct task_struct *a = _a; |
87 | struct ce_dom_data *ce_data = dom->data; | 61 | const domain_t *dom = get_task_domain(a); |
62 | const struct ce_dom_data *ce_data = dom->data; | ||
88 | return (a == ce_data->should_schedule); | 63 | return (a == ce_data->should_schedule); |
89 | } | 64 | } |
90 | 65 | ||
91 | void __mc_ce_timer_callback(struct hrtimer *timer); | 66 | void ce_domain_init(domain_t *dom, |
92 | static enum hrtimer_restart ce_timer_function(struct hrtimer *timer) | 67 | raw_spinlock_t *lock, |
93 | { | 68 | requeue_t requeue, |
94 | /* need to lock? */ | 69 | peek_ready_t peek_ready, |
95 | __mc_ce_timer_callback(timer); | 70 | take_ready_t take_ready, |
96 | return HRTIMER_RESTART; | 71 | preempt_needed_t preempt_needed, |
97 | } | 72 | task_prio_t task_prio, |
98 | 73 | struct ce_dom_data *dom_data, | |
99 | void mc_ce_release_at(struct task_struct*, lt_t); | 74 | const int cpu, |
100 | void ce_start(struct task_struct *ts, lt_t start) | 75 | ce_timer_callback_t ce_timer_callback) |
101 | { | ||
102 | mc_ce_release_at(ts, start); | ||
103 | } | ||
104 | |||
105 | long mc_ce_activate_plugin(void); | ||
106 | domain_t *ce_domain_for(int); | ||
107 | long ce_activate_plugin(void) | ||
108 | { | ||
109 | domain_t *dom; | ||
110 | struct ce_dom_data *ce_data; | ||
111 | int cpu; | ||
112 | |||
113 | /* first change the timer callback function */ | ||
114 | for_each_online_cpu(cpu) { | ||
115 | dom = ce_domain_for(cpu); | ||
116 | ce_data = dom->data; | ||
117 | ce_data->timer.function = ce_timer_function; | ||
118 | } | ||
119 | /* then run the regular CE activate plugin */ | ||
120 | return mc_ce_activate_plugin(); | ||
121 | } | ||
122 | |||
123 | long mc_ce_deactivate_plugin(void); | ||
124 | long ce_deactivate_plugin(void) | ||
125 | { | 76 | { |
126 | return mc_ce_deactivate_plugin(); | 77 | domain_init(dom, lock, requeue, peek_ready, take_ready, preempt_needed, |
78 | task_prio); | ||
79 | dom->data = dom_data; | ||
80 | dom_data->cpu = cpu; | ||
81 | hrtimer_start_on_info_init(&dom_data->timer_info); | ||
82 | hrtimer_init(&dom_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); | ||
83 | dom_data->timer.function = ce_timer_callback; | ||
127 | } | 84 | } |