diff options
Diffstat (limited to 'include/litmus/budget.h')
-rw-r--r-- | include/litmus/budget.h | 106 |
1 files changed, 80 insertions, 26 deletions
diff --git a/include/litmus/budget.h b/include/litmus/budget.h index 763b31c0e9f6..2a3511245f7a 100644 --- a/include/litmus/budget.h +++ b/include/litmus/budget.h | |||
@@ -1,26 +1,14 @@ | |||
1 | #ifndef _LITMUS_BUDGET_H_ | 1 | #ifndef _LITMUS_BUDGET_H_ |
2 | #define _LITMUS_BUDGET_H_ | 2 | #define _LITMUS_BUDGET_H_ |
3 | 3 | ||
4 | /* Update the per-processor enforcement timer (arm/reproram/cancel) for | 4 | #include <linux/hrtimer.h> |
5 | * the next task. */ | 5 | #include <linux/semaphore.h> |
6 | void update_enforcement_timer(struct task_struct* t); | ||
7 | 6 | ||
8 | /* Send SIG_BUDGET to a real-time task. */ | 7 | #define budget_exhausted(t) \ |
9 | void send_sigbudget(struct task_struct* t); | 8 | (get_exec_time(t) >= get_exec_cost(t)) |
10 | 9 | ||
11 | inline static int budget_exhausted(struct task_struct* t) | 10 | #define budget_remaining(t) \ |
12 | { | 11 | ((!budget_exhausted(t)) ? (get_exec_cost(t) - get_exec_time(t)) : 0) |
13 | return get_exec_time(t) >= get_exec_cost(t); | ||
14 | } | ||
15 | |||
16 | inline static lt_t budget_remaining(struct task_struct* t) | ||
17 | { | ||
18 | if (!budget_exhausted(t)) | ||
19 | return get_exec_cost(t) - get_exec_time(t); | ||
20 | else | ||
21 | /* avoid overflow */ | ||
22 | return 0; | ||
23 | } | ||
24 | 12 | ||
25 | #define budget_enforced(t) (\ | 13 | #define budget_enforced(t) (\ |
26 | tsk_rt(t)->task_params.budget_policy != NO_ENFORCEMENT) | 14 | tsk_rt(t)->task_params.budget_policy != NO_ENFORCEMENT) |
@@ -29,21 +17,87 @@ inline static lt_t budget_remaining(struct task_struct* t) | |||
29 | tsk_rt(t)->task_params.budget_policy == PRECISE_ENFORCEMENT || \ | 17 | tsk_rt(t)->task_params.budget_policy == PRECISE_ENFORCEMENT || \ |
30 | tsk_rt(t)->task_params.budget_signal_policy == PRECISE_SIGNALS) | 18 | tsk_rt(t)->task_params.budget_signal_policy == PRECISE_SIGNALS) |
31 | 19 | ||
20 | #define budget_quantum_tracked(t) (\ | ||
21 | tsk_rt(t)->task_params.budget_policy == QUANTUM_ENFORCEMENT || \ | ||
22 | tsk_rt(t)->task_params.budget_signal_policy == QUANTUM_SIGNALS) | ||
23 | |||
32 | #define budget_signalled(t) (\ | 24 | #define budget_signalled(t) (\ |
33 | tsk_rt(t)->task_params.budget_signal_policy != NO_SIGNALS) | 25 | tsk_rt(t)->task_params.budget_signal_policy != NO_SIGNALS) |
34 | 26 | ||
35 | #define budget_precisely_signalled(t) (\ | 27 | #define budget_precisely_signalled(t) (\ |
36 | tsk_rt(t)->task_params.budget_policy == PRECISE_SIGNALS) | 28 | tsk_rt(t)->task_params.budget_policy == PRECISE_SIGNALS) |
37 | 29 | ||
38 | #define sigbudget_sent(t) (\ | 30 | #define bt_flag_is_set(t, flag_nr) (\ |
39 | test_bit(RT_JOB_SIG_BUDGET_SENT, &tsk_rt(t)->job_params.flags)) | 31 | test_bit(flag_nr, &tsk_rt(t)->budget.flags)) |
32 | |||
33 | #define bt_flag_test_and_set(t, flag_nr) (\ | ||
34 | test_and_set_bit(flag_nr, &tsk_rt(t)->budget.flags)) | ||
35 | |||
36 | #define bt_flag_set(t, flag_nr) (\ | ||
37 | set_bit(flag_nr, &tsk_rt(t)->budget.flags)) | ||
38 | |||
39 | #define bt_flag_clear(t, flag_nr) (\ | ||
40 | clear_bit(flag_nr, &tsk_rt(t)->budget.flags)) | ||
41 | |||
42 | #define bt_flags_reset(t) (\ | ||
43 | tsk_rt(t)->budget.flags = 0) | ||
44 | |||
45 | #define requeue_preempted_job(t) \ | ||
46 | (t && (!budget_exhausted(t) || !budget_enforced(t))) | ||
47 | |||
48 | struct enforcement_timer | ||
49 | { | ||
50 | raw_spinlock_t lock; | ||
51 | struct hrtimer timer; | ||
52 | int armed:1; | ||
53 | }; | ||
54 | |||
55 | typedef void (*scheduled_t)(struct task_struct* t); | ||
56 | typedef void (*blocked_t)(struct task_struct* t); | ||
57 | typedef void (*preempt_or_sleep_t)(struct task_struct* t); | ||
58 | typedef void (*exhausted_t)(struct task_struct* t); | ||
59 | typedef void (*exit_t)(struct task_struct* t); | ||
40 | 60 | ||
41 | static inline int requeue_preempted_job(struct task_struct* t) | 61 | struct budget_tracker_ops |
42 | { | 62 | { |
43 | /* Add task to ready queue only if not subject to budget enforcement or | 63 | scheduled_t on_scheduled; /* called from litmus_schedule(). */ |
44 | * if the job has budget remaining. t may be NULL. | 64 | blocked_t on_blocked; /* called from plugin::schedule() */ |
45 | */ | 65 | preempt_or_sleep_t on_preempt_or_sleep; /* called from plugin::schedule() */ |
46 | return t && (!budget_exhausted(t) || !budget_enforced(t)); | 66 | |
47 | } | 67 | exit_t on_exit; /* task exiting rt mode */ |
68 | |||
69 | exhausted_t on_exhausted; /* called by plugin::tick() or timer interrupt */ | ||
70 | }; | ||
71 | |||
72 | struct budget_tracker | ||
73 | { | ||
74 | struct enforcement_timer timer; | ||
75 | const struct budget_tracker_ops* ops; | ||
76 | unsigned long flags; | ||
77 | }; | ||
78 | |||
79 | /* budget tracker flags */ | ||
80 | enum BT_FLAGS | ||
81 | { | ||
82 | BTF_BUDGET_EXHAUSTED = 0, | ||
83 | BTF_SIG_BUDGET_SENT = 1, | ||
84 | }; | ||
85 | |||
86 | /* Functions for simple DRAIN_SIMPLE policy common | ||
87 | * to every scheduler. Scheduler must provided | ||
88 | * implementation for simple_on_exhausted(). | ||
89 | */ | ||
90 | void simple_on_scheduled(struct task_struct* t); | ||
91 | void simple_on_blocked(struct task_struct* t); | ||
92 | void simple_on_preempt_or_sleep(struct task_struct* t); | ||
93 | void simple_on_exit(struct task_struct* t); | ||
94 | |||
95 | |||
96 | void init_budget_tracker(struct budget_tracker* bt, | ||
97 | const struct budget_tracker_ops* ops); | ||
98 | |||
99 | |||
100 | /* Send SIG_BUDGET to a real-time task. */ | ||
101 | void send_sigbudget(struct task_struct* t); | ||
48 | 102 | ||
49 | #endif | 103 | #endif |