diff options
Diffstat (limited to 'include/litmus/litmus.h')
-rw-r--r-- | include/litmus/litmus.h | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/include/litmus/litmus.h b/include/litmus/litmus.h index ce24e62eee81..4fa705e65f0c 100644 --- a/include/litmus/litmus.h +++ b/include/litmus/litmus.h | |||
@@ -95,6 +95,126 @@ void litmus_exit_task(struct task_struct *tsk); | |||
95 | #define is_be(t) \ | 95 | #define is_be(t) \ |
96 | (tsk_rt(t)->task_params.cls == RT_CLASS_BEST_EFFORT) | 96 | (tsk_rt(t)->task_params.cls == RT_CLASS_BEST_EFFORT) |
97 | 97 | ||
98 | |||
99 | |||
100 | /* budget-related functions and macros */ | ||
101 | |||
102 | inline static int budget_exhausted(struct task_struct* t) { | ||
103 | return get_exec_time(t) >= get_exec_cost(t); | ||
104 | } | ||
105 | |||
106 | inline static int budget_remaining(struct task_struct* t) { | ||
107 | return (!budget_exhausted(t)) ? (get_exec_cost(t) - get_exec_time(t)) : 0; | ||
108 | } | ||
109 | |||
110 | #define budget_enforced(t) (\ | ||
111 | tsk_rt(t)->task_params.budget_policy != NO_ENFORCEMENT) | ||
112 | |||
113 | #define budget_precisely_tracked(t) (\ | ||
114 | tsk_rt(t)->task_params.budget_policy == PRECISE_ENFORCEMENT || \ | ||
115 | tsk_rt(t)->task_params.budget_signal_policy == PRECISE_SIGNALS) | ||
116 | |||
117 | #define budget_quantum_tracked(t) (\ | ||
118 | tsk_rt(t)->task_params.budget_policy == QUANTUM_ENFORCEMENT || \ | ||
119 | tsk_rt(t)->task_params.budget_signal_policy == QUANTUM_SIGNALS) | ||
120 | |||
121 | #define budget_signalled(t) (\ | ||
122 | tsk_rt(t)->task_params.budget_signal_policy != NO_SIGNALS) | ||
123 | |||
124 | #define budget_precisely_signalled(t) (\ | ||
125 | tsk_rt(t)->task_params.budget_policy == PRECISE_SIGNALS) | ||
126 | |||
127 | #define bt_flag_is_set(t, flag_nr) (\ | ||
128 | test_bit(flag_nr, &tsk_rt(t)->budget.flags)) | ||
129 | |||
130 | #define bt_flag_test_and_set(t, flag_nr) (\ | ||
131 | test_and_set_bit(flag_nr, &tsk_rt(t)->budget.flags)) | ||
132 | |||
133 | #define bt_flag_set(t, flag_nr) (\ | ||
134 | set_bit(flag_nr, &tsk_rt(t)->budget.flags)) | ||
135 | |||
136 | #define bt_flag_clear(t, flag_nr) (\ | ||
137 | clear_bit(flag_nr, &tsk_rt(t)->budget.flags)) | ||
138 | |||
139 | #define bt_flags_reset(t) (\ | ||
140 | tsk_rt(t)->budget.flags = 0) | ||
141 | |||
142 | #define requeue_preempted_job(t) \ | ||
143 | (t && (!budget_exhausted(t) || !budget_enforced(t))) | ||
144 | |||
145 | |||
146 | #ifdef CONFIG_LITMUS_LOCKING | ||
147 | static inline void set_inh_task_linkback(struct task_struct* t, struct task_struct* linkto) | ||
148 | { | ||
149 | const int MAX_IDX = BITS_PER_LONG - 1; | ||
150 | |||
151 | int success = 0; | ||
152 | int old_idx = tsk_rt(t)->inh_task_linkback_idx; | ||
153 | |||
154 | /* is the linkback already set? */ | ||
155 | if (old_idx >= 0 && old_idx <= MAX_IDX) { | ||
156 | if ((BIT_MASK(old_idx) & tsk_rt(linkto)->used_linkback_slots) && | ||
157 | (tsk_rt(linkto)->inh_task_linkbacks[old_idx] == t)) { | ||
158 | TRACE_TASK(t, "linkback is current.\n"); | ||
159 | return; | ||
160 | } | ||
161 | BUG(); | ||
162 | } | ||
163 | |||
164 | /* kludge: upper limit on num linkbacks */ | ||
165 | BUG_ON(tsk_rt(linkto)->used_linkback_slots == ~0ul); | ||
166 | |||
167 | while(!success) { | ||
168 | int b = find_first_zero_bit(&tsk_rt(linkto)->used_linkback_slots, | ||
169 | sizeof(tsk_rt(linkto)->used_linkback_slots)); | ||
170 | |||
171 | BUG_ON(b > MAX_IDX); | ||
172 | |||
173 | /* set bit... */ | ||
174 | if (!test_and_set_bit(b, &tsk_rt(linkto)->used_linkback_slots)) { | ||
175 | TRACE_TASK(t, "linking back to %s/%d in slot %d\n", linkto->comm, linkto->pid, b); | ||
176 | if (tsk_rt(linkto)->inh_task_linkbacks[b]) | ||
177 | TRACE_TASK(t, "%s/%d already has %s/%d in slot %d\n", | ||
178 | linkto->comm, linkto->pid, | ||
179 | tsk_rt(linkto)->inh_task_linkbacks[b]->comm, | ||
180 | tsk_rt(linkto)->inh_task_linkbacks[b]->pid, | ||
181 | b); | ||
182 | |||
183 | /* TODO: allow dirty data to remain in [b] after code is tested */ | ||
184 | BUG_ON(tsk_rt(linkto)->inh_task_linkbacks[b] != NULL); | ||
185 | /* ...before setting slot */ | ||
186 | tsk_rt(linkto)->inh_task_linkbacks[b] = t; | ||
187 | tsk_rt(t)->inh_task_linkback_idx = b; | ||
188 | success = 1; | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | |||
193 | static inline void clear_inh_task_linkback(struct task_struct* t, struct task_struct* linkedto) | ||
194 | { | ||
195 | const int MAX_IDX = BITS_PER_LONG - 1; | ||
196 | |||
197 | int success = 0; | ||
198 | int slot = tsk_rt(t)->inh_task_linkback_idx; | ||
199 | |||
200 | if (slot < 0) { | ||
201 | TRACE_TASK(t, "assuming linkback already cleared.\n"); | ||
202 | return; | ||
203 | } | ||
204 | |||
205 | BUG_ON(slot > MAX_IDX); | ||
206 | BUG_ON(tsk_rt(linkedto)->inh_task_linkbacks[slot] != t); | ||
207 | |||
208 | /* be safe - clear slot before clearing the bit */ | ||
209 | tsk_rt(t)->inh_task_linkback_idx = -1; | ||
210 | tsk_rt(linkedto)->inh_task_linkbacks[slot] = NULL; | ||
211 | |||
212 | success = test_and_clear_bit(slot, &tsk_rt(linkedto)->used_linkback_slots); | ||
213 | |||
214 | BUG_ON(!success); | ||
215 | } | ||
216 | #endif | ||
217 | |||
98 | /* Our notion of time within LITMUS: kernel monotonic time. */ | 218 | /* Our notion of time within LITMUS: kernel monotonic time. */ |
99 | static inline lt_t litmus_clock(void) | 219 | static inline lt_t litmus_clock(void) |
100 | { | 220 | { |