diff options
author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2014-09-04 19:39:41 -0400 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2014-09-04 19:39:41 -0400 |
commit | 85533ddcfa62fdb273d2f33e5e729ad1461f771a (patch) | |
tree | 595997b54d06c51af184e0d0645ae808f07f8f56 | |
parent | 8685f881d61617142f2ab0847359d870b8a76d36 (diff) |
Switch table-driven reservations to use table-driven budget
Instead of counting how much budget has been consumed, determine
budget based on actual time slots.
-rw-r--r-- | include/litmus/polling_reservations.h | 1 | ||||
-rw-r--r-- | litmus/polling_reservations.c | 54 |
2 files changed, 51 insertions, 4 deletions
diff --git a/include/litmus/polling_reservations.h b/include/litmus/polling_reservations.h index 15910ed7ef8b..fa221817ad30 100644 --- a/include/litmus/polling_reservations.h +++ b/include/litmus/polling_reservations.h | |||
@@ -24,6 +24,7 @@ struct table_driven_reservation { | |||
24 | unsigned int next_interval; | 24 | unsigned int next_interval; |
25 | unsigned int num_intervals; | 25 | unsigned int num_intervals; |
26 | struct lt_interval *intervals; | 26 | struct lt_interval *intervals; |
27 | struct lt_interval *cur_interval; | ||
27 | }; | 28 | }; |
28 | 29 | ||
29 | void table_driven_reservation_init(struct table_driven_reservation *tdres, | 30 | void table_driven_reservation_init(struct table_driven_reservation *tdres, |
diff --git a/litmus/polling_reservations.c b/litmus/polling_reservations.c index 08034c3556e4..e6c57f592780 100644 --- a/litmus/polling_reservations.c +++ b/litmus/polling_reservations.c | |||
@@ -366,15 +366,29 @@ static lt_t td_interval_length(struct lt_interval *ival) | |||
366 | return ival->end - ival->start; | 366 | return ival->end - ival->start; |
367 | } | 367 | } |
368 | 368 | ||
369 | static lt_t td_time_remaining_until_end(struct table_driven_reservation *tdres) | ||
370 | { | ||
371 | lt_t now = tdres->res.env->current_time; | ||
372 | lt_t end = td_cur_major_cycle_start(tdres) + tdres->cur_interval->end; | ||
373 | TRACE("td_remaining(%u): start=%llu now=%llu end=%llu\n", | ||
374 | tdres->res.id, | ||
375 | td_cur_major_cycle_start(tdres) + tdres->cur_interval->start, | ||
376 | now, end); | ||
377 | if (now >= end) | ||
378 | return 0; | ||
379 | else | ||
380 | return end - now; | ||
381 | } | ||
382 | |||
369 | static void td_replenish( | 383 | static void td_replenish( |
370 | struct reservation *res | 384 | struct reservation *res) |
371 | ) | ||
372 | { | 385 | { |
373 | struct table_driven_reservation *tdres = | 386 | struct table_driven_reservation *tdres = |
374 | container_of(res, struct table_driven_reservation, res); | 387 | container_of(res, struct table_driven_reservation, res); |
375 | 388 | ||
376 | /* replenish budget */ | 389 | /* replenish budget */ |
377 | res->cur_budget = td_interval_length(tdres->intervals + tdres->next_interval); | 390 | tdres->cur_interval = tdres->intervals + tdres->next_interval; |
391 | res->cur_budget = td_interval_length(tdres->cur_interval); | ||
378 | 392 | ||
379 | tdres->next_interval = (tdres->next_interval + 1) % tdres->num_intervals; | 393 | tdres->next_interval = (tdres->next_interval + 1) % tdres->num_intervals; |
380 | if (tdres->next_interval) | 394 | if (tdres->next_interval) |
@@ -404,12 +418,43 @@ static void td_replenish( | |||
404 | } | 418 | } |
405 | } | 419 | } |
406 | 420 | ||
421 | static void td_drain_budget( | ||
422 | struct reservation *res, | ||
423 | lt_t how_much) | ||
424 | { | ||
425 | struct table_driven_reservation *tdres = | ||
426 | container_of(res, struct table_driven_reservation, res); | ||
427 | |||
428 | /* Table-driven scheduling: instead of tracking the budget, we compute | ||
429 | * how much time is left in this allocation interval. */ | ||
430 | |||
431 | switch (res->state) { | ||
432 | case RESERVATION_DEPLETED: | ||
433 | case RESERVATION_INACTIVE: | ||
434 | BUG(); | ||
435 | break; | ||
436 | |||
437 | case RESERVATION_ACTIVE_IDLE: | ||
438 | case RESERVATION_ACTIVE: | ||
439 | res->cur_budget = td_time_remaining_until_end(tdres); | ||
440 | TRACE("td_drain_budget(%u): drained to budget=%llu\n", | ||
441 | res->id, res->cur_budget); | ||
442 | if (!res->cur_budget) { | ||
443 | res->env->change_state(res->env, res, | ||
444 | RESERVATION_DEPLETED); | ||
445 | } /* else: stay in current state */ | ||
446 | break; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | |||
451 | |||
407 | static struct reservation_ops td_ops = { | 452 | static struct reservation_ops td_ops = { |
408 | .dispatch_client = default_dispatch_client, | 453 | .dispatch_client = default_dispatch_client, |
409 | .client_arrives = td_client_arrives, | 454 | .client_arrives = td_client_arrives, |
410 | .client_departs = td_client_departs, | 455 | .client_departs = td_client_departs, |
411 | .replenish = td_replenish, | 456 | .replenish = td_replenish, |
412 | .drain_budget = common_drain_budget, | 457 | .drain_budget = td_drain_budget, |
413 | }; | 458 | }; |
414 | 459 | ||
415 | void table_driven_reservation_init( | 460 | void table_driven_reservation_init( |
@@ -431,6 +476,7 @@ void table_driven_reservation_init( | |||
431 | reservation_init(&tdres->res); | 476 | reservation_init(&tdres->res); |
432 | tdres->major_cycle = major_cycle; | 477 | tdres->major_cycle = major_cycle; |
433 | tdres->intervals = intervals; | 478 | tdres->intervals = intervals; |
479 | tdres->cur_interval = intervals; | ||
434 | tdres->num_intervals = num_intervals; | 480 | tdres->num_intervals = num_intervals; |
435 | tdres->res.ops = &td_ops; | 481 | tdres->res.ops = &td_ops; |
436 | } | 482 | } |