aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern B. Brandenburg <bbb@cs.unc.edu>2009-12-08 11:35:42 -0500
committerBjoern B. Brandenburg <bbb@cs.unc.edu>2009-12-08 12:47:01 -0500
commit5b4aa5ab69fa1971e04eff5eaa797a7ef19eff3e (patch)
treeacc6929a8d0081842890240b99dec2b94399c420
parentc5707739e831d559035fae06ded312644b01e766 (diff)
add common EDF functions
-rw-r--r--include/litmus/edf_common.h26
-rw-r--r--litmus/Makefile1
-rw-r--r--litmus/edf_common.c103
3 files changed, 130 insertions, 0 deletions
diff --git a/include/litmus/edf_common.h b/include/litmus/edf_common.h
new file mode 100644
index 0000000000..5060926a42
--- /dev/null
+++ b/include/litmus/edf_common.h
@@ -0,0 +1,26 @@
1/* EDF common data structures and utility functions shared by all EDF
2 * based scheduler plugins
3 */
4
5/* CLEANUP: Add comments and make it less messy.
6 *
7 */
8
9#ifndef __UNC_EDF_COMMON_H__
10#define __UNC_EDF_COMMON_H__
11
12#include <litmus/rt_domain.h>
13
14
15void edf_domain_init(rt_domain_t* rt, check_resched_needed_t resched,
16 release_jobs_t release);
17
18int edf_higher_prio(struct task_struct* first,
19 struct task_struct* second);
20int edf_ready_order(struct heap_node* a, struct heap_node* b);
21
22int edf_preemption_needed(rt_domain_t* rt, struct task_struct *t);
23
24int edf_set_hp_task(struct pi_semaphore *sem);
25int edf_set_hp_cpu_task(struct pi_semaphore *sem, int cpu);
26#endif
diff --git a/litmus/Makefile b/litmus/Makefile
index 576c1ded20..59f61cbc7f 100644
--- a/litmus/Makefile
+++ b/litmus/Makefile
@@ -6,6 +6,7 @@ obj-y = sched_plugin.o litmus.o \
6 jobs.o \ 6 jobs.o \
7 sync.o \ 7 sync.o \
8 rt_domain.o \ 8 rt_domain.o \
9 edf_common.o \
9 heap.o 10 heap.o
10 11
11obj-$(CONFIG_FEATHER_TRACE) += ft_event.o ftdev.o 12obj-$(CONFIG_FEATHER_TRACE) += ft_event.o ftdev.o
diff --git a/litmus/edf_common.c b/litmus/edf_common.c
new file mode 100644
index 0000000000..8149e0c5a2
--- /dev/null
+++ b/litmus/edf_common.c
@@ -0,0 +1,103 @@
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
16#include <litmus/edf_common.h>
17
18/* edf_higher_prio - returns true if first has a higher EDF priority
19 * than second. Deadline ties are broken by PID.
20 *
21 * both first and second may be NULL
22 */
23int edf_higher_prio(struct task_struct* first,
24 struct task_struct* second)
25{
26 struct task_struct *first_task = first;
27 struct task_struct *second_task = second;
28
29 /* There is no point in comparing a task to itself. */
30 if (first && first == second) {
31 TRACE_TASK(first,
32 "WARNING: pointless edf priority comparison.\n");
33 return 0;
34 }
35
36
37 /* Check for inherited priorities. Change task
38 * used for comparison in such a case.
39 */
40 if (first && first->rt_param.inh_task)
41 first_task = first->rt_param.inh_task;
42 if (second && second->rt_param.inh_task)
43 second_task = second->rt_param.inh_task;
44
45 return
46 /* it has to exist in order to have higher priority */
47 first_task && (
48 /* does the second task exist and is it a real-time task? If
49 * not, the first task (which is a RT task) has higher
50 * priority.
51 */
52 !second_task || !is_realtime(second_task) ||
53
54 /* is the deadline of the first task earlier?
55 * Then it has higher priority.
56 */
57 earlier_deadline(first_task, second_task) ||
58
59 /* Do we have a deadline tie?
60 * Then break by PID.
61 */
62 (get_deadline(first_task) == get_deadline(second_task) &&
63 (first_task->pid < second_task->pid ||
64
65 /* If the PIDs are the same then the task with the inherited
66 * priority wins.
67 */
68 (first_task->pid == second_task->pid &&
69 !second->rt_param.inh_task))));
70}
71
72int edf_ready_order(struct heap_node* a, struct heap_node* b)
73{
74 return edf_higher_prio(heap2task(a), heap2task(b));
75}
76
77void edf_domain_init(rt_domain_t* rt, check_resched_needed_t resched,
78 release_jobs_t release)
79{
80 rt_domain_init(rt, edf_ready_order, resched, release);
81}
82
83/* need_to_preempt - check whether the task t needs to be preempted
84 * call only with irqs disabled and with ready_lock acquired
85 * THIS DOES NOT TAKE NON-PREEMPTIVE SECTIONS INTO ACCOUNT!
86 */
87int edf_preemption_needed(rt_domain_t* rt, struct task_struct *t)
88{
89 /* we need the read lock for edf_ready_queue */
90 /* no need to preempt if there is nothing pending */
91 if (!__jobs_pending(rt))
92 return 0;
93 /* we need to reschedule if t doesn't exist */
94 if (!t)
95 return 1;
96
97 /* NOTE: We cannot check for non-preemptibility since we
98 * don't know what address space we're currently in.
99 */
100
101 /* make sure to get non-rt stuff out of the way */
102 return !is_realtime(t) || edf_higher_prio(__next_ready(rt), t);
103}