aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/edf_common.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-30 16:43:52 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-30 16:43:52 -0400
commit62f2907f445b08f958acf1cc1a0c29736d4ba206 (patch)
treea11743eddcc125c9c3ac0c527078338e3d01b295 /litmus/edf_common.c
parentd0961e328a2a4c026c884c768b798cb882922708 (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.c71
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 */
22int edf_higher_prio(struct task_struct* first, 27#ifdef CONFIG_LITMUS_NESTED_LOCKING
23 struct task_struct* second) 28int __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
32int 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
107int 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
112int 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
120int 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
125int 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
133int 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
87int edf_ready_order(struct bheap_node* a, struct bheap_node* b) 140int 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));