aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/edf_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/edf_common.c')
-rw-r--r--litmus/edf_common.c102
1 files changed, 102 insertions, 0 deletions
diff --git a/litmus/edf_common.c b/litmus/edf_common.c
new file mode 100644
index 000000000000..97e37761cedc
--- /dev/null
+++ b/litmus/edf_common.c
@@ -0,0 +1,102 @@
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/* edf_higher_prio - returns true if first has a higher EDF priority
18 * than second. Deadline ties are broken by PID.
19 *
20 * both first and second may be NULL
21 */
22int edf_higher_prio(struct task_struct* first,
23 struct task_struct* second)
24{
25 struct task_struct *first_task = first;
26 struct task_struct *second_task = second;
27
28 /* There is no point in comparing a task to itself. */
29 if (first && first == second) {
30 TRACE_TASK(first,
31 "WARNING: pointless edf priority comparison.\n");
32 return 0;
33 }
34
35
36 /* Check for inherited priorities. Change task
37 * used for comparison in such a case.
38 */
39 if (first && first->rt_param.inh_task)
40 first_task = first->rt_param.inh_task;
41 if (second && second->rt_param.inh_task)
42 second_task = second->rt_param.inh_task;
43
44 return
45 /* it has to exist in order to have higher priority */
46 first_task && (
47 /* does the second task exist and is it a real-time task? If
48 * not, the first task (which is a RT task) has higher
49 * priority.
50 */
51 !second_task || !is_realtime(second_task) ||
52
53 /* is the deadline of the first task earlier?
54 * Then it has higher priority.
55 */
56 earlier_deadline(first_task, second_task) ||
57
58 /* Do we have a deadline tie?
59 * Then break by PID.
60 */
61 (get_deadline(first_task) == get_deadline(second_task) &&
62 (first_task->pid < second_task->pid ||
63
64 /* If the PIDs are the same then the task with the inherited
65 * priority wins.
66 */
67 (first_task->pid == second_task->pid &&
68 !second->rt_param.inh_task))));
69}
70
71int edf_ready_order(struct heap_node* a, struct heap_node* b)
72{
73 return edf_higher_prio(heap2task(a), heap2task(b));
74}
75
76void edf_domain_init(rt_domain_t* rt, check_resched_needed_t resched,
77 release_jobs_t release)
78{
79 rt_domain_init(rt, edf_ready_order, resched, release);
80}
81
82/* need_to_preempt - check whether the task t needs to be preempted
83 * call only with irqs disabled and with ready_lock acquired
84 * THIS DOES NOT TAKE NON-PREEMPTIVE SECTIONS INTO ACCOUNT!
85 */
86int edf_preemption_needed(rt_domain_t* rt, struct task_struct *t)
87{
88 /* we need the read lock for edf_ready_queue */
89 /* no need to preempt if there is nothing pending */
90 if (!__jobs_pending(rt))
91 return 0;
92 /* we need to reschedule if t doesn't exist */
93 if (!t)
94 return 1;
95
96 /* NOTE: We cannot check for non-preemptibility since we
97 * don't know what address space we're currently in.
98 */
99
100 /* make sure to get non-rt stuff out of the way */
101 return !is_realtime(t) || edf_higher_prio(__next_ready(rt), t);
102}