blob: 6b4889c40bca76517bf903189538dd3a5f2678d7 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
#include <linux/mm.h>
#include <litmus/litmus.h>
#include <litmus/bheap.h>
#include <litmus/rt_domain.h>
#include <litmus/reservations/ext_reservation.h>
struct release_heap* release_heap_alloc(int gfp_flags);
void release_heap_free(struct release_heap* rh);
int higher_res_prio(struct reservation* first,
struct reservation* second)
{
struct reservation *first_task = first;
struct reservation *second_task = second;
/* There is no point in comparing a reservation to itself. */
if (first && first == second) {
return 0;
}
/* check for NULL reservations */
if (!first || !second)
return first && !second;
#ifdef CONFIG_LITMUS_LOCKING
// SOMEWHAT HACKY -- guarantee that a non-preemptive reservation
// is higher-priority than any other; fall back to regular
// priority-checking if both are non-preemptive or both are preemptive
if (first->ops->is_np(first, -1) != second->ops->is_np(second, -1))
return first->ops->is_np(first, -1);
/* Check for inherited priorities. Change reservation
* used for comparison in such a case.
*/
if (unlikely(first->inh_res))
first_task = first->inh_res;
if (unlikely(second->inh_res))
second_task = second->inh_res;
#endif
if (first_task->priority > second_task->priority) {
return 1;
}
else if (first_task->priority == second_task->priority) {
/* Tie break by pid */
if (first_task->id < second_task->id) {
return 1;
}
#ifdef CONFIG_LITMUS_LOCKING
else if (first_task->id == second_task->id) {
/* If the PIDs are the same then the task with the
* inherited priority wins.
*/
if (!second->inh_res) {
return 1;
}
}
#endif
}
return 0; /* fall-through. prio(second_task) > prio(first_task) */
}
void init_ext_reservation(
struct reservation* res,
unsigned int id,
struct reservation_ops* ops)
{
res->id = id;
res->ops = ops;
res->heap_node = bheap_node_alloc(GFP_ATOMIC);
res->rel_heap = release_heap_alloc(GFP_ATOMIC);
bheap_node_init(&res->heap_node, res);
INIT_LIST_HEAD(&res->ln);
INIT_LIST_HEAD(&res->all_list);
}
void clean_up_ext_reservation(struct reservation* res)
{
bheap_node_free(res->heap_node);
release_heap_free(res->rel_heap);
}
|