aboutsummaryrefslogtreecommitdiffstats
path: root/include/litmus/litmus.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/litmus/litmus.h')
-rw-r--r--include/litmus/litmus.h120
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
102inline static int budget_exhausted(struct task_struct* t) {
103 return get_exec_time(t) >= get_exec_cost(t);
104}
105
106inline 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) (\
111tsk_rt(t)->task_params.budget_policy != NO_ENFORCEMENT)
112
113#define budget_precisely_tracked(t) (\
114tsk_rt(t)->task_params.budget_policy == PRECISE_ENFORCEMENT || \
115tsk_rt(t)->task_params.budget_signal_policy == PRECISE_SIGNALS)
116
117#define budget_quantum_tracked(t) (\
118tsk_rt(t)->task_params.budget_policy == QUANTUM_ENFORCEMENT || \
119tsk_rt(t)->task_params.budget_signal_policy == QUANTUM_SIGNALS)
120
121#define budget_signalled(t) (\
122tsk_rt(t)->task_params.budget_signal_policy != NO_SIGNALS)
123
124#define budget_precisely_signalled(t) (\
125tsk_rt(t)->task_params.budget_policy == PRECISE_SIGNALS)
126
127#define bt_flag_is_set(t, flag_nr) (\
128test_bit(flag_nr, &tsk_rt(t)->budget.flags))
129
130#define bt_flag_test_and_set(t, flag_nr) (\
131test_and_set_bit(flag_nr, &tsk_rt(t)->budget.flags))
132
133#define bt_flag_set(t, flag_nr) (\
134set_bit(flag_nr, &tsk_rt(t)->budget.flags))
135
136#define bt_flag_clear(t, flag_nr) (\
137clear_bit(flag_nr, &tsk_rt(t)->budget.flags))
138
139#define bt_flags_reset(t) (\
140tsk_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
147static 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
193static 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. */
99static inline lt_t litmus_clock(void) 219static inline lt_t litmus_clock(void)
100{ 220{