aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhoon Kim <namhoonk@cs.unc.edu>2015-01-21 15:54:21 -0500
committerNamhoon Kim <namhoonk@cs.unc.edu>2015-01-21 15:54:21 -0500
commit16a64e75ff5d1deeeb8adaaa0d11b1d6fe236bbe (patch)
tree02c8bfade500a847e039ea340c1583d40d1e9fd6
parent6583dcfbda43e420921e3adf7f2e46dc719e8d26 (diff)
Initial lv C impl.wip-mc2
-rw-r--r--include/litmus/reservation.h55
-rw-r--r--litmus/polling_reservations.c1
-rw-r--r--litmus/reservation.c303
-rw-r--r--litmus/sched_mc2.c453
4 files changed, 739 insertions, 73 deletions
diff --git a/include/litmus/reservation.h b/include/litmus/reservation.h
index 4eecd3f088e8..0345d3482916 100644
--- a/include/litmus/reservation.h
+++ b/include/litmus/reservation.h
@@ -126,6 +126,9 @@ struct reservation {
126 struct reservation_ops *ops; 126 struct reservation_ops *ops;
127 127
128 struct list_head clients; 128 struct list_head clients;
129
130 /* for global env. */
131 int scheduled_on;
129}; 132};
130 133
131void reservation_init(struct reservation *res); 134void reservation_init(struct reservation *res);
@@ -191,4 +194,56 @@ struct task_struct* sup_dispatch(struct sup_reservation_environment* sup_env);
191struct reservation* sup_find_by_id(struct sup_reservation_environment* sup_env, 194struct reservation* sup_find_by_id(struct sup_reservation_environment* sup_env,
192 unsigned int id); 195 unsigned int id);
193 196
197#define ENV_RESCHEDULE_NOW (0)
198#define ENV_NO_SCHEDULER_UPDATE (ULLONG_MAX)
199
200struct next_timer_event {
201 lt_t next_event;
202 int timer_armed_on;
203 struct list_head list;
204};
205
206/* A global multiprocessor reservation environment.
207 */
208struct gmp_reservation_environment {
209 //raw_spinlock_t lock;
210 struct reservation_environment env;
211
212 /* ordered by priority */
213 struct list_head active_reservations;
214
215 /* ordered by next_replenishment */
216 struct list_head depleted_reservations;
217
218 /* unordered */
219 struct list_head inactive_reservations;
220
221 /* - ENV_RESCHEDULE_NOW means call gmp_dispatch() now
222 * - ENV_NO_SCHEDULER_UPDATE means nothing to do
223 * any other value means program a timer for the given time
224 */
225 struct list_head next_events;
226 raw_spinlock_t event_lock;
227 bool schedule_now;
228 /* set to true if a call to gmp_dispatch() is imminent */
229 bool will_schedule;
230};
231
232/* Contract:
233 * - before calling into sup_ code, or any reservation methods,
234 * update the time with sup_update_time(); and
235 * - after calling into sup_ code, or any reservation methods,
236 * check next_scheduler_update and program timer or trigger
237 * scheduler invocation accordingly.
238 */
239
240void gmp_init(struct gmp_reservation_environment* gmp_env);
241void gmp_add_new_reservation(struct gmp_reservation_environment* gmp_env,
242 struct reservation* new_res);
243void gmp_update_time(struct gmp_reservation_environment* gmp_env, lt_t now);
244struct task_struct* gmp_dispatch(struct gmp_reservation_environment* gmp_env);
245
246struct reservation* gmp_find_by_id(struct gmp_reservation_environment* gmp_env,
247 unsigned int id);
248
194#endif 249#endif
diff --git a/litmus/polling_reservations.c b/litmus/polling_reservations.c
index 4c07ee74bf39..81f8e0f54ffd 100644
--- a/litmus/polling_reservations.c
+++ b/litmus/polling_reservations.c
@@ -72,6 +72,7 @@ static void periodic_polling_client_departs(
72 /* do nothing */ 72 /* do nothing */
73 break; 73 break;
74 } 74 }
75 res->scheduled_on = NO_CPU;
75} 76}
76 77
77static void periodic_polling_on_replenishment( 78static void periodic_polling_on_replenishment(
diff --git a/litmus/reservation.c b/litmus/reservation.c
index 0e43479ff2e1..35b3b5de5d0c 100644
--- a/litmus/reservation.c
+++ b/litmus/reservation.c
@@ -1,4 +1,5 @@
1#include <linux/sched.h> 1#include <linux/sched.h>
2#include <linux/slab.h>
2 3
3#include <litmus/litmus.h> 4#include <litmus/litmus.h>
4#include <litmus/reservation.h> 5#include <litmus/reservation.h>
@@ -203,8 +204,7 @@ static void sup_charge_budget(
203 { 204 {
204 /* make sure scheduler is invoked when this reservation expires 205 /* make sure scheduler is invoked when this reservation expires
205 * its remaining budget */ 206 * its remaining budget */
206 TRACE("requesting scheduler update for reservation %u in %llu nanoseconds\n", 207 //TRACE("requesting scheduler update for reservation %u in %llu nanoseconds\n", res->id, res->cur_budget);
207 res->id, res->cur_budget);
208 sup_scheduler_update_after(sup_env, res->cur_budget); 208 sup_scheduler_update_after(sup_env, res->cur_budget);
209 } 209 }
210 if (encountered_active) 210 if (encountered_active)
@@ -317,3 +317,302 @@ void sup_init(struct sup_reservation_environment* sup_env)
317 317
318 sup_env->next_scheduler_update = SUP_NO_SCHEDULER_UPDATE; 318 sup_env->next_scheduler_update = SUP_NO_SCHEDULER_UPDATE;
319} 319}
320
321static void gmp_scheduler_update_at(
322 struct gmp_reservation_environment* gmp_env,
323 lt_t when)
324{
325 struct next_timer_event *nevent;
326 struct list_head *pos;
327 struct next_timer_event *queued;
328 int found = 0;
329
330 nevent = kzalloc(sizeof(*nevent), GFP_KERNEL);
331 nevent->next_event = when;
332 nevent->timer_armed_on = NO_CPU;
333
334 list_for_each(pos, &gmp_env->next_events) {
335 queued = list_entry(pos, struct next_timer_event, list);
336 if (queued->next_event > nevent->next_event) {
337 list_add(&nevent->list, pos->prev);
338 found = 1;
339 TRACE("NEXT_EVENT ADDED after %llu\n", queued->next_event);
340 break;
341 }
342 }
343
344 if (!found) {
345 list_add_tail(&nevent->list, &gmp_env->next_events);
346 TRACE("NEXT_EVENT ADDED at [0]\n");
347 }
348
349 TRACE("GMP_SCHEDULER_UPDATE_AT update_time: %llu\n", nevent->next_event);
350}
351
352static void gmp_scheduler_update_after(
353 struct gmp_reservation_environment* gmp_env,
354 lt_t timeout)
355{
356 gmp_scheduler_update_at(gmp_env, gmp_env->env.current_time + timeout);
357}
358
359static int _gmp_queue_depleted(
360 struct gmp_reservation_environment* gmp_env,
361 struct reservation *res)
362{
363 struct list_head *pos;
364 struct reservation *queued;
365 int passed_earlier = 0;
366
367 list_for_each(pos, &gmp_env->depleted_reservations) {
368 queued = list_entry(pos, struct reservation, list);
369 if (queued->next_replenishment > res->next_replenishment) {
370 list_add(&res->list, pos->prev);
371 return passed_earlier;
372 } else
373 passed_earlier = 1;
374 }
375
376 list_add_tail(&res->list, &gmp_env->depleted_reservations);
377
378 return passed_earlier;
379}
380
381static void gmp_queue_depleted(
382 struct gmp_reservation_environment* gmp_env,
383 struct reservation *res)
384{
385 int passed_earlier = _gmp_queue_depleted(gmp_env, res);
386
387 /* check for updated replenishment time */
388 if (!passed_earlier)
389 gmp_scheduler_update_at(gmp_env, res->next_replenishment);
390}
391
392static int _gmp_queue_active(
393 struct gmp_reservation_environment* gmp_env,
394 struct reservation *res)
395{
396 struct list_head *pos;
397 struct reservation *queued;
398 int passed_active = 0;
399
400 list_for_each(pos, &gmp_env->active_reservations) {
401 queued = list_entry(pos, struct reservation, list);
402 if (queued->priority > res->priority) {
403 list_add(&res->list, pos->prev);
404 return passed_active;
405 } else if (queued->state == RESERVATION_ACTIVE)
406 passed_active = 1;
407 }
408
409 list_add_tail(&res->list, &gmp_env->active_reservations);
410 return passed_active;
411}
412
413static void gmp_queue_active(
414 struct gmp_reservation_environment* gmp_env,
415 struct reservation *res)
416{
417 int passed_active = _gmp_queue_active(gmp_env, res);
418
419 /* check for possible preemption */
420 if (res->state == RESERVATION_ACTIVE && !passed_active) {
421 gmp_env->schedule_now = true;