blob: 72f04777e0b080d40d40731d37ec1d069c77cf13 (
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#ifndef _LITMUS_BUDGET_H_
#define _LITMUS_BUDGET_H_
#include <linux/hrtimer.h>
#include <linux/semaphore.h>
#define budget_exhausted(t) \
(get_exec_time(t) >= get_exec_cost(t))
#define budget_remaining(t) \
((!budget_exhausted(t)) ? (get_exec_cost(t) - get_exec_time(t)) : 0)
#define budget_enforced(t) (\
tsk_rt(t)->task_params.budget_policy != NO_ENFORCEMENT)
#define budget_precisely_tracked(t) (\
tsk_rt(t)->task_params.budget_policy == PRECISE_ENFORCEMENT || \
tsk_rt(t)->task_params.budget_signal_policy == PRECISE_SIGNALS)
#define budget_quantum_tracked(t) (\
tsk_rt(t)->task_params.budget_policy == QUANTUM_ENFORCEMENT || \
tsk_rt(t)->task_params.budget_signal_policy == QUANTUM_SIGNALS)
#define budget_signalled(t) (\
tsk_rt(t)->task_params.budget_signal_policy != NO_SIGNALS)
#define budget_precisely_signalled(t) (\
tsk_rt(t)->task_params.budget_policy == PRECISE_SIGNALS)
#define bt_flag_is_set(t, flag_nr) (\
test_bit(flag_nr, &tsk_rt(t)->budget.flags))
#define bt_flag_test_and_set(t, flag_nr) (\
test_and_set_bit(flag_nr, &tsk_rt(t)->budget.flags))
#define bt_flag_set(t, flag_nr) (\
set_bit(flag_nr, &tsk_rt(t)->budget.flags))
#define bt_flag_clear(t, flag_nr) (\
clear_bit(flag_nr, &tsk_rt(t)->budget.flags))
#define bt_flags_reset(t) (\
tsk_rt(t)->budget.flags = 0)
#define requeue_preempted_job(t) \
(t && (!budget_exhausted(t) || !budget_enforced(t)))
struct enforcement_timer
{
raw_spinlock_t lock;
struct hrtimer timer;
int armed:1;
};
typedef void (*scheduled_t)(struct task_struct* t);
typedef void (*blocked_t)(struct task_struct* t);
typedef void (*preempt_t)(struct task_struct* t);
typedef void (*sleep_t)(struct task_struct* t);
typedef enum hrtimer_restart (*exhausted_t)(struct task_struct* t);
typedef void (*exit_t)(struct task_struct* t);
struct budget_tracker_ops
{
scheduled_t on_scheduled; /* called from litmus_schedule(). */
blocked_t on_blocked; /* called from plugin::schedule() */
preempt_t on_preempt; /* called from plugin::schedule() */
sleep_t on_sleep; /* called from plugin::schedule() */
exit_t on_exit; /* task exiting rt mode */
exhausted_t on_exhausted; /* called by plugin::tick() or timer interrupt */
};
struct budget_tracker
{
struct enforcement_timer timer;
const struct budget_tracker_ops* ops;
unsigned long flags;
};
/* budget tracker flags */
enum BT_FLAGS
{
BTF_BUDGET_EXHAUSTED = 0,
BTF_SIG_BUDGET_SENT = 1,
};
/* Functions for simple DRAIN_SIMPLE policy common
* to every scheduler. Scheduler must provide
* implementation for simple_on_exhausted().
*/
void simple_on_scheduled(struct task_struct* t);
void simple_on_blocked(struct task_struct* t);
void simple_on_preempt(struct task_struct* t);
void simple_on_sleep(struct task_struct* t);
void simple_on_exit(struct task_struct* t);
/* Functions for DRAIN_SOBLIV policy common
* to every scheduler. Scheduler must provide
* implementation for sobliv_on_exhausted().
*
* Limitation: Quantum budget tracking is unsupported.
*/
void sobliv_on_scheduled(struct task_struct* t);
void sobliv_on_blocked(struct task_struct* t);
void sobliv_on_sleep(struct task_struct* t);
/* Use the DRAIN_SIMPLE implementations */
#define sobliv_on_preempt simple_on_preempt
#define sobliv_on_exit simple_on_exit
void init_budget_tracker(struct budget_tracker* bt,
const struct budget_tracker_ops* ops);
/* Send SIG_BUDGET to a real-time task. */
void send_sigbudget(struct task_struct* t);
#endif
|