aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/fp_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'litmus/fp_common.c')
-rw-r--r--litmus/fp_common.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/litmus/fp_common.c b/litmus/fp_common.c
new file mode 100644
index 000000000000..fa36574d5992
--- /dev/null
+++ b/litmus/fp_common.c
@@ -0,0 +1,112 @@
1/*
2 * litmus/fp_common.c
3 *
4 * Common functions for fixed-priority 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/fp_common.h>
16
17/* fp_higher_prio - returns true if first has a higher static priority
18 * than second. Deadline ties are broken by PID.
19 *
20 * both first and second may be NULL
21 */
22int fp_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 FP priority comparison.\n");
32 return 0;
33 }
34
35
36 /* check for NULL tasks */
37 if (!first || !second)
38 return first && !second;
39
40#ifdef CONFIG_LITMUS_LOCKING
41
42 /* Check for inherited priorities. Change task
43 * used for comparison in such a case.
44 */
45 if (unlikely(first->rt_param.inh_task))
46 first_task = first->rt_param.inh_task;
47 if (unlikely(second->rt_param.inh_task))
48 second_task = second->rt_param.inh_task;
49
50 /* Check for priority boosting. Tie-break by start of boosting.
51 */
52 if (unlikely(is_priority_boosted(first_task))) {
53 /* first_task is boosted, how about second_task? */
54 if (!is_priority_boosted(second_task) ||
55 lt_before(get_boost_start(first_task),
56 get_boost_start(second_task)))
57 return 1;
58 else
59 return 0;
60 } else if (unlikely(is_priority_boosted(second_task)))
61 /* second_task is boosted, first is not*/
62 return 0;
63
64#endif
65
66
67 return !is_realtime(second_task) ||
68
69 /* is the deadline of the first task earlier?
70 * Then it has higher priority.
71 */
72 get_priority(first_task) < get_priority(second_task) ||
73
74 /* Do we have a deadline tie?
75 * Then break by PID.
76 */
77 (get_priority(first_task) == get_priority(second_task) &&
78 (first_task->pid < second_task->pid ||
79
80 /* If the PIDs are the same then the task with the inherited
81 * priority wins.
82 */
83 (first_task->pid == second_task->pid &&
84 !second->rt_param.inh_task)));
85}
86
87int fp_ready_order(struct bheap_node* a, struct bheap_node* b)
88{
89 return fp_higher_prio(bheap2task(a), bheap2task(b));
90}
91
92void fp_domain_init(rt_domain_t* rt, check_resched_needed_t resched,
93 release_jobs_t release)
94{
95 rt_domain_init(rt, fp_ready_order, resched, release);
96}
97
98/* need_to_preempt - check whether the task t needs to be preempted
99 */
100int fp_preemption_needed(rt_domain_t* rt, struct task_struct *t)
101{
102 /* we need the read lock for edf_ready_queue */
103 /* no need to preempt if there is nothing pending */
104 if (!__jobs_pending(rt))
105 return 0;
106 /* we need to reschedule if t doesn't exist */
107 if (!t)
108 return 1;
109
110 /* make sure to get non-rt stuff out of the way */
111 return !is_realtime(t) || fp_higher_prio(__next_ready(rt), t);
112}