diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-10-08 17:06:48 -0400 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2011-10-08 17:06:48 -0400 |
commit | 5a2b8be93c93f2c66edee2a8aff1554778959e35 (patch) | |
tree | 931b54656e800f89b5479be520b9a9ca29ed6030 /litmus/ce_domain.c | |
parent | 61ce17e3edbf33e49adb5536c9904b735e58c774 (diff) |
Fixed timer issue and atomic remove issue in level A domain.
Timers had an issue where they couldn't be cancelled before they migrated.
Now when you set the start_on_info to inactive, it will prevent a timer
from being armed.
When a task is being blocked and preempted concurrently, the blocking code
needs to be able to prevent the task from being scheduled on another CPU.
This did not work for CE domains. Added a per-domain remove function
which, for ce domains, will prevent a task from being returned by the domain.
Diffstat (limited to 'litmus/ce_domain.c')
-rw-r--r-- | litmus/ce_domain.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/litmus/ce_domain.c b/litmus/ce_domain.c index c3ddc9dd63ad..5e1f7ccc000c 100644 --- a/litmus/ce_domain.c +++ b/litmus/ce_domain.c | |||
@@ -30,6 +30,8 @@ void ce_requeue(domain_t *dom, struct task_struct *ts) | |||
30 | "expected_job: %3u\n", | 30 | "expected_job: %3u\n", |
31 | asleep, just_finished, expected_job); | 31 | asleep, just_finished, expected_job); |
32 | 32 | ||
33 | tsk_mc_data(ts)->mc_task.lvl_a_eligible = 1; | ||
34 | |||
33 | /* When coming from job completion, the task will be asleep. */ | 35 | /* When coming from job completion, the task will be asleep. */ |
34 | if (asleep && just_finished < expected_job) { | 36 | if (asleep && just_finished < expected_job) { |
35 | TRACE_MC_TASK(ts, "appears behind\n"); | 37 | TRACE_MC_TASK(ts, "appears behind\n"); |
@@ -41,18 +43,27 @@ void ce_requeue(domain_t *dom, struct task_struct *ts) | |||
41 | } | 43 | } |
42 | 44 | ||
43 | /* | 45 | /* |
46 | * | ||
47 | */ | ||
48 | void ce_remove(domain_t *dom, struct task_struct *ts) | ||
49 | { | ||
50 | tsk_mc_data(ts)->mc_task.lvl_a_eligible = 0; | ||
51 | } | ||
52 | |||
53 | /* | ||
44 | * ce_take_ready and ce_peek_ready | 54 | * ce_take_ready and ce_peek_ready |
45 | */ | 55 | */ |
46 | struct task_struct* ce_peek_and_take_ready(domain_t *dom) | 56 | struct task_struct* ce_peek_and_take_ready(domain_t *dom) |
47 | { | 57 | { |
48 | struct task_struct *ret = NULL; | ||
49 | const struct ce_dom_data *ce_data = dom->data; | 58 | const struct ce_dom_data *ce_data = dom->data; |
50 | const int exists = NULL != ce_data->should_schedule; | 59 | struct task_struct *ret = NULL, *sched = ce_data->should_schedule; |
51 | const int blocked = exists && !is_running(ce_data->should_schedule); | 60 | const int exists = NULL != sched; |
61 | const int blocked = exists && !is_running(sched); | ||
62 | const int elig = exists && tsk_mc_data(sched)->mc_task.lvl_a_eligible; | ||
52 | 63 | ||
53 | /* Return the task we should schedule if it is not blocked or sleeping. */ | 64 | /* Return the task we should schedule if it is not blocked or sleeping. */ |
54 | if (exists && !blocked) | 65 | if (exists && !blocked && elig) |
55 | ret = ce_data->should_schedule; | 66 | ret = sched; |
56 | return ret; | 67 | return ret; |
57 | } | 68 | } |
58 | 69 | ||
@@ -78,6 +89,7 @@ void ce_domain_init(domain_t *dom, | |||
78 | domain_init(dom, lock, requeue, peek_ready, take_ready, preempt_needed, | 89 | domain_init(dom, lock, requeue, peek_ready, take_ready, preempt_needed, |
79 | task_prio); | 90 | task_prio); |
80 | dom->data = dom_data; | 91 | dom->data = dom_data; |
92 | dom->remove = ce_remove; | ||
81 | dom_data->cpu = cpu; | 93 | dom_data->cpu = cpu; |
82 | #ifdef CONFIG_MERGE_TIMERS | 94 | #ifdef CONFIG_MERGE_TIMERS |
83 | init_event(&dom_data->event, CRIT_LEVEL_A, ce_timer_callback, | 95 | init_event(&dom_data->event, CRIT_LEVEL_A, ce_timer_callback, |