diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-30 16:43:52 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-30 16:43:52 -0400 |
commit | 62f2907f445b08f958acf1cc1a0c29736d4ba206 (patch) | |
tree | a11743eddcc125c9c3ac0c527078338e3d01b295 /litmus/edf_common.c | |
parent | d0961e328a2a4c026c884c768b798cb882922708 (diff) |
Nested inheritance with fine-grained locking.
Minor hack to lockdep was required too allow
the inheritance propagation locking logic to
work.
Diffstat (limited to 'litmus/edf_common.c')
-rw-r--r-- | litmus/edf_common.c | 71 |
1 files changed, 62 insertions, 9 deletions
diff --git a/litmus/edf_common.c b/litmus/edf_common.c index 54cfada586be..7a3a9a02a703 100644 --- a/litmus/edf_common.c +++ b/litmus/edf_common.c | |||
@@ -12,15 +12,25 @@ | |||
12 | #include <litmus/sched_plugin.h> | 12 | #include <litmus/sched_plugin.h> |
13 | #include <litmus/sched_trace.h> | 13 | #include <litmus/sched_trace.h> |
14 | 14 | ||
15 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | ||
16 | #include <litmus/locking.h> | ||
17 | #endif | ||
18 | |||
15 | #include <litmus/edf_common.h> | 19 | #include <litmus/edf_common.h> |
16 | 20 | ||
21 | |||
17 | /* edf_higher_prio - returns true if first has a higher EDF priority | 22 | /* edf_higher_prio - returns true if first has a higher EDF priority |
18 | * than second. Deadline ties are broken by PID. | 23 | * than second. Deadline ties are broken by PID. |
19 | * | 24 | * |
20 | * both first and second may be NULL | 25 | * both first and second may be NULL |
21 | */ | 26 | */ |
22 | int edf_higher_prio(struct task_struct* first, | 27 | #ifdef CONFIG_LITMUS_NESTED_LOCKING |
23 | struct task_struct* second) | 28 | int __edf_higher_prio( |
29 | struct task_struct* first, comparison_mode_t first_mode, | ||
30 | struct task_struct* second, comparison_mode_t second_mode) | ||
31 | #else | ||
32 | int edf_higher_prio(struct task_struct* first, struct task_struct* second) | ||
33 | #endif | ||
24 | { | 34 | { |
25 | struct task_struct *first_task = first; | 35 | struct task_struct *first_task = first; |
26 | struct task_struct *second_task = second; | 36 | struct task_struct *second_task = second; |
@@ -38,14 +48,23 @@ int edf_higher_prio(struct task_struct* first, | |||
38 | return first && !second; | 48 | return first && !second; |
39 | 49 | ||
40 | #ifdef CONFIG_LITMUS_LOCKING | 50 | #ifdef CONFIG_LITMUS_LOCKING |
41 | |||
42 | /* Check for inherited priorities. Change task | 51 | /* Check for inherited priorities. Change task |
43 | * used for comparison in such a case. | 52 | * used for comparison in such a case. |
44 | */ | 53 | */ |
45 | if (unlikely(first->rt_param.eff_prio)) | 54 | if (unlikely(first->rt_param.inh_task) |
46 | first_task = first->rt_param.eff_prio; | 55 | #ifdef CONFIG_LITMUS_NESTED_LOCKING |
47 | if (unlikely(second->rt_param.eff_prio)) | 56 | && (first_mode == INHERITED) |
48 | second_task = second->rt_param.eff_prio; | 57 | #endif |
58 | ) { | ||
59 | first_task = first->rt_param.inh_task; | ||
60 | } | ||
61 | if (unlikely(second->rt_param.inh_task) | ||
62 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | ||
63 | && (second_mode == INHERITED) | ||
64 | #endif | ||
65 | ) { | ||
66 | second_task = second->rt_param.inh_task; | ||
67 | } | ||
49 | 68 | ||
50 | /* Check for priority boosting. Tie-break by start of boosting. | 69 | /* Check for priority boosting. Tie-break by start of boosting. |
51 | */ | 70 | */ |
@@ -63,7 +82,6 @@ int edf_higher_prio(struct task_struct* first, | |||
63 | 82 | ||
64 | #endif | 83 | #endif |
65 | 84 | ||
66 | |||
67 | return !is_realtime(second_task) || | 85 | return !is_realtime(second_task) || |
68 | 86 | ||
69 | /* is the deadline of the first task earlier? | 87 | /* is the deadline of the first task earlier? |
@@ -81,9 +99,44 @@ int edf_higher_prio(struct task_struct* first, | |||
81 | * priority wins. | 99 | * priority wins. |
82 | */ | 100 | */ |
83 | (first_task->pid == second_task->pid && | 101 | (first_task->pid == second_task->pid && |
84 | !second->rt_param.eff_prio))); | 102 | !second->rt_param.inh_task))); |
103 | } | ||
104 | |||
105 | |||
106 | #ifdef CONFIG_LITMUS_NESTED_LOCKING | ||
107 | int edf_higher_prio(struct task_struct* first, struct task_struct* second) | ||
108 | { | ||
109 | return __edf_higher_prio(first, INHERITED, second, INHERITED); | ||
85 | } | 110 | } |
86 | 111 | ||
112 | int edf_max_heap_order(struct binheap_node *a, struct binheap_node *b) | ||
113 | { | ||
114 | struct litmus_lock *l_a = (struct litmus_lock *)binheap_entry(a, struct litmus_lock, hp_binheap_node); | ||
115 | struct litmus_lock *l_b = (struct litmus_lock *)binheap_entry(b, struct litmus_lock, hp_binheap_node); | ||
116 | |||
117 | return __edf_higher_prio(l_a->hp_waiter_eff_prio, INHERITED, l_b->hp_waiter_eff_prio, INHERITED); | ||
118 | } | ||
119 | |||
120 | int edf_min_heap_order(struct binheap_node *a, struct binheap_node *b) | ||
121 | { | ||
122 | return edf_max_heap_order(b, a); // swap comparison | ||
123 | } | ||
124 | |||
125 | int edf_max_heap_base_priority_order(struct binheap_node *a, struct binheap_node *b) | ||
126 | { | ||
127 | struct litmus_lock *l_a = (struct litmus_lock *)binheap_entry(a, struct litmus_lock, hp_binheap_node); | ||
128 | struct litmus_lock *l_b = (struct litmus_lock *)binheap_entry(b, struct litmus_lock, hp_binheap_node); | ||
129 | |||
130 | return __edf_higher_prio(l_a->hp_waiter_eff_prio, BASE, l_b->hp_waiter_eff_prio, BASE); | ||
131 | } | ||
132 | |||
133 | int edf_min_heap_base_priority_order(struct binheap_node *a, struct binheap_node *b) | ||
134 | { | ||
135 | return edf_max_heap_base_priority_order(b, a); // swap comparison | ||
136 | } | ||
137 | #endif | ||
138 | |||
139 | |||
87 | int edf_ready_order(struct bheap_node* a, struct bheap_node* b) | 140 | int edf_ready_order(struct bheap_node* a, struct bheap_node* b) |
88 | { | 141 | { |
89 | return edf_higher_prio(bheap2task(a), bheap2task(b)); | 142 | return edf_higher_prio(bheap2task(a), bheap2task(b)); |