diff options
author | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-03-23 08:20:51 -0400 |
---|---|---|
committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2016-03-23 08:20:51 -0400 |
commit | ff210e0441b743890ad85c7335e41894b34a1431 (patch) | |
tree | 21027c2433f5ca9a26731b3af72fa6eb620df369 /include/litmus/reservation.h | |
parent | 2e23e3f0cc7c3249b510e94b5b3ec92577b67e81 (diff) |
MC2 scheduler and partition modules
Diffstat (limited to 'include/litmus/reservation.h')
-rw-r--r-- | include/litmus/reservation.h | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/include/litmus/reservation.h b/include/litmus/reservation.h new file mode 100644 index 000000000000..7e022b34470f --- /dev/null +++ b/include/litmus/reservation.h | |||
@@ -0,0 +1,256 @@ | |||
1 | #ifndef LITMUS_RESERVATION_H | ||
2 | #define LITMUS_RESERVATION_H | ||
3 | |||
4 | #include <linux/list.h> | ||
5 | #include <linux/hrtimer.h> | ||
6 | |||
7 | struct reservation_client; | ||
8 | struct reservation_environment; | ||
9 | struct reservation; | ||
10 | |||
11 | typedef enum { | ||
12 | /* reservation has no clients, is not consuming budget */ | ||
13 | RESERVATION_INACTIVE = 0, | ||
14 | |||
15 | /* reservation has clients, consumes budget when scheduled */ | ||
16 | RESERVATION_ACTIVE, | ||
17 | |||
18 | /* reservation has no clients, but may be consuming budget */ | ||
19 | RESERVATION_ACTIVE_IDLE, | ||
20 | |||
21 | /* Reservation has no budget and waits for | ||
22 | * replenishment. May or may not have clients. */ | ||
23 | RESERVATION_DEPLETED, | ||
24 | } reservation_state_t; | ||
25 | |||
26 | |||
27 | /* ************************************************************************** */ | ||
28 | |||
29 | /* Select which task to dispatch. If NULL is returned, it means there is nothing | ||
30 | * to schedule right now and background work can be scheduled. */ | ||
31 | typedef struct task_struct * (*dispatch_t) ( | ||
32 | struct reservation_client *client | ||
33 | ); | ||
34 | |||
35 | /* Something that can be managed in a reservation and that can yield | ||
36 | * a process for dispatching. Contains a pointer to the reservation | ||
37 | * to which it "belongs". */ | ||
38 | struct reservation_client { | ||
39 | struct list_head list; | ||
40 | struct reservation* reservation; | ||
41 | dispatch_t dispatch; | ||
42 | }; | ||
43 | |||
44 | |||
45 | /* ************************************************************************** */ | ||
46 | |||
47 | /* Called by reservations to request state change. */ | ||
48 | typedef void (*reservation_change_state_t) ( | ||
49 | struct reservation_environment* env, | ||
50 | struct reservation *res, | ||
51 | reservation_state_t new_state | ||
52 | ); | ||
53 | |||
54 | /* The framework within wich reservations operate. */ | ||
55 | struct reservation_environment { | ||
56 | lt_t time_zero; | ||
57 | lt_t current_time; | ||
58 | |||
59 | /* services invoked by reservations */ | ||
60 | reservation_change_state_t change_state; | ||
61 | }; | ||
62 | |||
63 | |||
64 | /* ************************************************************************** */ | ||
65 | |||
66 | /* A new client is added or an existing client resumes. */ | ||
67 | typedef void (*client_arrives_t) ( | ||
68 | struct reservation *reservation, | ||
69 | struct reservation_client *client | ||
70 | ); | ||
71 | |||
72 | /* A client suspends or terminates. */ | ||
73 | typedef void (*client_departs_t) ( | ||
74 | struct reservation *reservation, | ||
75 | struct reservation_client *client, | ||
76 | int did_signal_job_completion | ||
77 | ); | ||
78 | |||
79 | /* A previously requested replenishment has occurred. */ | ||
80 | typedef void (*on_replenishment_timer_t) ( | ||
81 | struct reservation *reservation | ||
82 | ); | ||
83 | |||
84 | /* Update the reservation's budget to reflect execution or idling. */ | ||
85 | typedef void (*drain_budget_t) ( | ||
86 | struct reservation *reservation, | ||
87 | lt_t how_much | ||
88 | ); | ||
89 | |||
90 | /* Select a ready task from one of the clients for scheduling. */ | ||
91 | typedef struct task_struct* (*dispatch_client_t) ( | ||
92 | struct reservation *reservation, | ||
93 | lt_t *time_slice /* May be used to force rescheduling after | ||
94 | some amount of time. 0 => no limit */ | ||
95 | ); | ||
96 | |||
97 | |||
98 | struct reservation_ops { | ||
99 | dispatch_client_t dispatch_client; | ||
100 | |||
101 | client_arrives_t client_arrives; | ||
102 | client_departs_t client_departs; | ||
103 | |||
104 | on_replenishment_timer_t replenish; | ||
105 | drain_budget_t drain_budget; | ||
106 | }; | ||
107 | |||
108 | struct reservation { | ||
109 | /* used to queue in environment */ | ||
110 | struct list_head list; | ||
111 | |||
112 | reservation_state_t state; | ||
113 | unsigned int id; | ||
114 | |||
115 | /* exact meaning defined by impl. */ | ||
116 | lt_t priority; | ||
117 | lt_t cur_budget; | ||
118 | lt_t next_replenishment; | ||
119 | |||
120 | /* budget stats */ | ||
121 | lt_t budget_consumed; /* how much budget consumed in this allocation cycle? */ | ||
122 | lt_t budget_consumed_total; | ||
123 | |||
124 | /* interaction with framework */ | ||
125 | struct reservation_environment *env; | ||
126 | struct reservation_ops *ops; | ||
127 | |||
128 | struct list_head clients; | ||
129 | |||
130 | /* for global env. */ | ||
131 | int scheduled_on; | ||
132 | int event_added; | ||
133 | /* for blocked by ghost. Do not charge budget when ACTIVE */ | ||
134 | int blocked_by_ghost; | ||
135 | /* ghost_job. If it is clear, do not charge budget when ACTIVE_IDLE */ | ||
136 | int is_ghost; | ||
137 | }; | ||
138 | |||
139 | void reservation_init(struct reservation *res); | ||
140 | |||
141 | /* Default implementations */ | ||
142 | |||
143 | /* simply select the first client in the list, set *for_at_most to zero */ | ||
144 | struct task_struct* default_dispatch_client( | ||
145 | struct reservation *res, | ||
146 | lt_t *for_at_most | ||
147 | ); | ||
148 | |||
149 | /* "connector" reservation client to hook up tasks with reservations */ | ||
150 | struct task_client { | ||
151 | struct reservation_client client; | ||
152 | struct task_struct *task; | ||
153 | }; | ||
154 | |||
155 | void task_client_init(struct task_client *tc, struct task_struct *task, | ||
156 | struct reservation *reservation); | ||
157 | |||
158 | #define SUP_RESCHEDULE_NOW (0) | ||
159 | #define SUP_NO_SCHEDULER_UPDATE (ULLONG_MAX) | ||
160 | |||
161 | /* A simple uniprocessor (SUP) flat (i.e., non-hierarchical) reservation | ||
162 | * environment. | ||
163 | */ | ||
164 | struct sup_reservation_environment { | ||
165 | struct reservation_environment env; | ||
166 | |||
167 | /* ordered by priority */ | ||
168 | struct list_head active_reservations; | ||
169 | |||
170 | /* ordered by next_replenishment */ | ||
171 | struct list_head depleted_reservations; | ||
172 | |||
173 | /* unordered */ | ||
174 | struct list_head inactive_reservations; | ||
175 | |||
176 | /* - SUP_RESCHEDULE_NOW means call sup_dispatch() now | ||
177 | * - SUP_NO_SCHEDULER_UPDATE means nothing to do | ||
178 | * any other value means program a timer for the given time | ||
179 | */ | ||
180 | lt_t next_scheduler_update; | ||
181 | /* set to true if a call to sup_dispatch() is imminent */ | ||
182 | bool will_schedule; | ||
183 | }; | ||
184 | |||
185 | /* Contract: | ||
186 | * - before calling into sup_ code, or any reservation methods, | ||
187 | * update the time with sup_update_time(); and | ||
188 | * - after calling into sup_ code, or any reservation methods, | ||
189 | * check next_scheduler_update and program timer or trigger | ||
190 | * scheduler invocation accordingly. | ||
191 | */ | ||
192 | |||
193 | void sup_init(struct sup_reservation_environment* sup_env); | ||
194 | void sup_add_new_reservation(struct sup_reservation_environment* sup_env, | ||
195 | struct reservation* new_res); | ||
196 | void sup_scheduler_update_after(struct sup_reservation_environment* sup_env, | ||
197 | lt_t timeout); | ||
198 | void sup_update_time(struct sup_reservation_environment* sup_env, lt_t now); | ||
199 | struct task_struct* sup_dispatch(struct sup_reservation_environment* sup_env); | ||
200 | |||
201 | struct reservation* sup_find_by_id(struct sup_reservation_environment* sup_env, | ||
202 | unsigned int id); | ||
203 | |||
204 | /* A global multiprocessor reservation environment. */ | ||
205 | |||
206 | typedef enum { | ||
207 | EVENT_REPLENISH = 0, | ||
208 | EVENT_DRAIN, | ||
209 | EVENT_OTHERS, | ||
210 | } event_type_t; | ||
211 | |||
212 | |||
213 | struct next_timer_event { | ||
214 | lt_t next_update; | ||
215 | int timer_armed_on; | ||
216 | unsigned int id; | ||
217 | event_type_t type; | ||
218 | struct list_head list; | ||
219 | }; | ||
220 | |||
221 | struct gmp_reservation_environment { | ||
222 | raw_spinlock_t lock; | ||
223 | struct reservation_environment env; | ||
224 | |||
225 | /* ordered by priority */ | ||
226 | struct list_head active_reservations; | ||
227 | |||
228 | /* ordered by next_replenishment */ | ||
229 | struct list_head depleted_reservations; | ||
230 | |||
231 | /* unordered */ | ||
232 | struct list_head inactive_reservations; | ||
233 | |||
234 | /* timer event ordered by next_update */ | ||
235 | struct list_head next_events; | ||
236 | |||
237 | /* (schedule_now == true) means call gmp_dispatch() now */ | ||
238 | int schedule_now; | ||
239 | /* set to true if a call to gmp_dispatch() is imminent */ | ||
240 | bool will_schedule; | ||
241 | }; | ||
242 | |||
243 | void gmp_init(struct gmp_reservation_environment* gmp_env); | ||
244 | void gmp_add_new_reservation(struct gmp_reservation_environment* gmp_env, | ||
245 | struct reservation* new_res); | ||
246 | void gmp_add_event_after(struct gmp_reservation_environment* gmp_env, | ||
247 | lt_t timeout, unsigned int id, event_type_t type); | ||
248 | void gmp_print_events(struct gmp_reservation_environment* gmp_env, lt_t now); | ||
249 | int gmp_update_time(struct gmp_reservation_environment* gmp_env, lt_t now); | ||
250 | struct task_struct* gmp_dispatch(struct gmp_reservation_environment* gmp_env); | ||
251 | struct next_timer_event* gmp_find_event_by_id(struct gmp_reservation_environment* gmp_env, unsigned int id); | ||
252 | struct next_timer_event* gmp_find_event_by_time(struct gmp_reservation_environment* gmp_env, lt_t when); | ||
253 | struct reservation* gmp_find_by_id(struct gmp_reservation_environment* gmp_env, | ||
254 | unsigned int id); | ||
255 | |||
256 | #endif | ||