aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/reservations/ext_reservation.c
blob: 0e02b8f2f877349bf1c210d30a406ac78205fb65 (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
#include <linux/slab.h>
#include <litmus/bheap.h>
#include <litmus/reservations/ext_reservation.h>

/* allocated in litmus.c */
extern struct kmem_cache* bheap_node_cache;
extern struct kmem_cache* release_heap_cache;

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

	/* 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
	}
	//TODO: TAKE INTO ACCOUNT INH_TASK WHEN DOING PRIO COMPARISONS
	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 = kmem_cache_alloc(bheap_node_cache, GFP_ATOMIC);
	res->rel_heap = kmem_cache_alloc(release_heap_cache, 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)
{
	kmem_cache_free(bheap_node_cache, res->heap_node);
	kmem_cache_free(release_heap_cache, res->rel_heap);
}