aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/edf_common.c
diff options
context:
space:
mode:
authorJeremy Erickson <jerickso@cs.unc.edu>2012-08-30 21:01:47 -0400
committerJeremy Erickson <jerickso@cs.unc.edu>2012-08-30 21:01:47 -0400
commitb1e1fea67bca3796d5f9133a92c300ec4fa93a4f (patch)
tree5cc1336e1fe1d6f93b1067e73e43381dd20db690 /litmus/edf_common.c
parentf6f94e2ab1b33f0082ac22d71f66385a60d8157f (diff)
Bjoern's Dissertation Code with Priority Donationwip-splitting-omlp-jerickso
Diffstat (limited to 'litmus/edf_common.c')
-rw-r--r--litmus/edf_common.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/litmus/edf_common.c b/litmus/edf_common.c
new file mode 100644
index 000000000000..c7d02ec2e15b
--- /dev/null
+++ b/litmus/edf_common.c
@@ -0,0 +1,143 @@
1/*
2 * kernel/edf_common.c
3 *
4 * Common functions for EDF based scheduler.
5 */
6
7#include <linux/percpu.h>
8#include <linux/sched.h>
9#include <linux/list.h>
10
11#include <litmus/litmus.h>
12#include <litmus/sched_plugin.h>
13#include <litmus/sched_trace.h>
14
15#include <litmus/edf_common.h>
16
17
18#ifdef CONFIG_LITMUS_LOCKING
19int edf_higher_base_prio(struct task_struct* first,
20 struct task_struct* second)
21{
22 struct task_struct *first_task = first;
23 struct task_struct *second_task = second;
24
25 /* check for NULL tasks */
26 if (!first || !second)
27 return first && !second;
28
29 return !is_realtime(second_task) ||
30 earlier_deadline(first_task, second_task) ||
31 (get_deadline(first_task) == get_deadline(second_task) &&
32 first_task->pid < second_task->pid);
33}
34
35int edf_pending_order(struct bheap_node* a, struct bheap_node* b)
36{
37 return edf_higher_base_prio(bheap2task(a), bheap2task(b));
38}
39
40#endif
41
42/* edf_higher_prio - returns true if first has a higher EDF priority
43 * than second. Deadline ties are broken by PID.
44 *
45 * both first and second may be NULL
46 */
47int edf_higher_prio(struct task_struct* first,
48 struct task_struct* second)
49{
50 struct task_struct *first_task = first;
51 struct task_struct *second_task = second;
52
53 /* There is no point in comparing a task to itself. */
54 if (first && first == second) {
55 TRACE_TASK(first,
56 "WARNING: pointless edf priority comparison.\n");
57 return 0;
58 }
59
60
61 /* check for NULL tasks */
62 if (!first || !second)
63 return first && !second;
64
65#ifdef CONFIG_LITMUS_LOCKING
66
67 /* Check for inherited priorities. Change task
68 * used for comparison in such a case.
69 */
70 if (unlikely(first->rt_param.inh_task))
71 first_task = first->rt_param.inh_task;
72 if (unlikely(second->rt_param.inh_task))
73 second_task = second->rt_param.inh_task;
74
75 /* Check for priority boosting. Tie-break by start of boosting.
76 */
77 if (unlikely(is_priority_boosted(first_task))) {
78 /* first_task is boosted, how about second_task? */
79 if (!is_priority_boosted(second_task) ||
80 lt_before(get_boost_start(first_task),
81 get_boost_start(second_task)))
82 return 1;
83 else
84 return 0;
85 } else if (unlikely(is_priority_boosted(second_task)))
86 /* second_task is boosted, first is not*/
87 return 0;
88
89#endif
90
91
92 return !is_realtime(second_task) ||
93
94 /* is the deadline of the first task earlier?
95 * Then it has higher priority.
96 */
97 earlier_deadline(first_task, second_task) ||
98
99 /* Do we have a deadline tie?
100 * Then break by PID.
101 */
102 (get_deadline(first_task) == get_deadline(second_task) &&
103 (first_task->pid < second_task->pid ||
104
105 /* If the PIDs are the same then the task with the inherited
106 * priority wins.
107 */
108 (first_task->pid == second_task->pid &&
109 !second->rt_param.inh_task)));
110}
111
112int edf_ready_order(struct bheap_node* a, struct bheap_node* b)
113{
114 return edf_higher_prio(bheap2task(a), bheap2task(b));
115}
116
117void edf_domain_init(rt_domain_t* rt, check_resched_needed_t resched,
118 release_jobs_t release)
119{
120 rt_domain_init(rt, edf_ready_order, resched, release);
121}
122
123/* need_to_preempt - check whether the task t needs to be preempted
124 * call only with irqs disabled and with ready_lock acquired
125 * THIS DOES NOT TAKE NON-PREEMPTIVE SECTIONS INTO ACCOUNT!
126 */
127int edf_preemption_needed(rt_domain_t* rt, struct task_struct *t)
128{
129 /* we need the read lock for edf_ready_queue */
130 /* no need to preempt if there is nothing pending */
131 if (!__jobs_pending(rt))
132 return 0;
133 /* we need to reschedule if t doesn't exist */
134 if (!t)
135 return 1;
136
137 /* NOTE: We cannot check for non-preemptibility since we
138 * don't know what address space we're currently in.
139 */
140
141 /* make sure to get non-rt stuff out of the way */
142 return !is_realtime(t) || edf_higher_prio(__next_ready(rt), t);
143}