aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/edzl_common.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2010-11-26 14:56:39 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2010-11-26 14:56:39 -0500
commit1baad08397910f4dee59e071808d74ea4ff8cf11 (patch)
treec8f24b6fb96da54e108d58a7423a027a95acaf61 /litmus/edzl_common.c
parent5c5456402d467969b217d7fdd6670f8c8600f5a8 (diff)
Implementation of EDZL
This patch implements the global EDZL scheduler. It is based heavily on the GSN-EDF implementation. Timers are used to detect zero-laxity points and issue the proper rescheduling operations.
Diffstat (limited to 'litmus/edzl_common.c')
-rw-r--r--litmus/edzl_common.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/litmus/edzl_common.c b/litmus/edzl_common.c
new file mode 100644
index 000000000000..f925901703ab
--- /dev/null
+++ b/litmus/edzl_common.c
@@ -0,0 +1,98 @@
1/*
2 * kernel/edzl_common.c
3 *
4 * Common functions for EDZL 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#include <litmus/edzl_common.h>
17
18int edzl_higher_prio(struct task_struct* first,
19 struct task_struct* second)
20{
21 struct task_struct *first_task = first;
22 struct task_struct *second_task = second;
23
24 /* There is no point in comparing a task to itself. */
25 if (first && first == second) {
26 TRACE_TASK(first,
27 "WARNING: pointless edf priority comparison.\n");
28 return 0;
29 }
30
31
32 /* Check for inherited priorities. Change task
33 * used for comparison in such a case.
34 */
35 if (first && first->rt_param.inh_task)
36 first_task = first->rt_param.inh_task;
37 if (second && second->rt_param.inh_task)
38 second_task = second->rt_param.inh_task;
39
40 /* null checks & rt checks */
41 if(!first_task)
42 return 0;
43 else if(!second_task || !is_realtime(second_task))
44 return 1;
45
46
47 if(likely(get_zerolaxity(first_task) == get_zerolaxity(second_task)))
48 {
49 /* edf order if both tasks have the same laxity state */
50 return(edf_higher_prio(first_task, second_task));
51 }
52 else
53 {
54 return(get_zerolaxity(first_task));
55 }
56}
57
58int edzl_ready_order(struct bheap_node* a, struct bheap_node* b)
59{
60 return edzl_higher_prio(bheap2task(a), bheap2task(b));
61}
62
63void edzl_domain_init(rt_domain_t* rt, check_resched_needed_t resched,
64 release_jobs_t release)
65{
66 rt_domain_init(rt, edzl_ready_order, resched, release);
67}
68
69/* need_to_preempt - check whether the task t needs to be preempted
70 * call only with irqs disabled and with ready_lock acquired
71 * THIS DOES NOT TAKE NON-PREEMPTIVE SECTIONS INTO ACCOUNT!
72 */
73int edzl_preemption_needed(rt_domain_t* rt, struct task_struct *t)
74{
75 /* we need the read lock for edf_ready_queue */
76 /* no need to preempt if there is nothing pending */
77 if (!__jobs_pending(rt))
78 return 0;
79 /* we need to reschedule if t doesn't exist */
80 if (!t)
81 return 1;
82 /* make sure to get non-rt stuff out of the way */
83 if (!is_realtime(t))
84 return 1;
85
86 /* NOTE: We cannot check for non-preemptibility since we
87 * don't know what address space we're currently in.
88 */
89
90 /* Detect zero-laxity as needed. Easier to do it here than in tick.
91 (No timer is used to detect zero-laxity while a job is running.) */
92 if(unlikely(!get_zerolaxity(t) && laxity_remaining(t) == 0))
93 {
94 set_zerolaxity(t, 1);
95 }
96
97 return edzl_higher_prio(__next_ready(rt), t);
98}