aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2012-05-06 16:16:09 -0400
committerJonathan Herman <hermanjl@cs.unc.edu>2012-05-06 16:16:09 -0400
commitaab1d2517ef6e9a8a4586d2d93718d1d8e717b95 (patch)
tree5b19f3cf579d071ef6c4c00215e32a7f8d5d32a8
parent8acf04cf81854a05d933a8236c2019b7b6d18bae (diff)
Added rm_common
-rw-r--r--litmus/rm_common.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/litmus/rm_common.c b/litmus/rm_common.c
new file mode 100644
index 000000000000..f608a084d3b8
--- /dev/null
+++ b/litmus/rm_common.c
@@ -0,0 +1,91 @@
1/*
2 * kernel/rm_common.c
3 *
4 * Common functions for RM 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/rm_common.h>
16
17/* rm_higher_prio - returns true if first has a higher RM priority
18 * than second. Deadline ties are broken by PID.
19 *
20 * both first and second may be NULL
21 */
22int rm_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 rm priority comparison.\n");
32 return 0;
33 }
34
35
36 /* check for NULL tasks */
37 if (!first || !second)
38 return first && !second;
39
40 return !is_realtime(second_task) ||
41
42 /* is the deadline of the first task earlier?
43 * Then it has higher priority.
44 */
45 lt_before(get_rt_period(first_task), get_rt_period(second_task)) ||
46
47 /* Do we have a deadline tie?
48 * Then break by PID.
49 */
50 (get_rt_period(first_task) == get_rt_period(second_task) &&
51 (first_task->pid < second_task->pid ||
52
53 /* If the PIDs are the same then the task with the inherited
54 * priority wins.
55 */
56 (first_task->pid == second_task->pid &&
57 !second->rt_param.inh_task)));
58}
59
60int rm_ready_order(struct bheap_node* a, struct bheap_node* b)
61{
62 return rm_higher_prio(bheap2task(a), bheap2task(b));
63}
64
65void rm_domain_init(rt_domain_t* rt, check_resched_needed_t resched,
66 release_jobs_t release)
67{
68 rt_domain_init(rt, rm_ready_order, resched, release);
69}
70
71/* need_to_preempt - check whether the task t needs to be preempted
72 * call only with irqs disabled and with ready_lock acquired
73 * THIS DOES NOT TAKE NON-PREEMPTIVE SECTIONS INTO ACCOUNT!
74 */
75int rm_preemption_needed(rt_domain_t* rt, struct task_struct *t)
76{
77 /* we need the read lock for rm_ready_queue */
78 /* no need to preempt if there is nothing pending */
79 if (!__jobs_pending(rt))
80 return 0;
81 /* we need to reschedule if t doesn't exist */
82 if (!t)
83 return 1;
84
85 /* NOTE: We cannot check for non-preemptibility since we
86 * don't know what address space we're currently in.
87 */
88
89 /* make sure to get non-rt stuff out of the way */
90 return !is_realtime(t) || rm_higher_prio(__next_ready(rt), t);
91}