diff options
author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2014-09-08 12:24:18 -0400 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2014-09-08 12:24:18 -0400 |
commit | e18fc708a32b2ee6b48e648cd2ac767eb76be5e5 (patch) | |
tree | 86a5383d0c4d2f22c29d96a9c0936f42fbf99ba5 | |
parent | 642d997fc6d6500e14f3c2fa72e481800d687cd1 (diff) |
Table-driven replenishments should depend on the current time
Make sure we don't accidentally bleed past the current reservation
scheduling slot (due to jitter) by determining the remaining budget
precisely when replenishing the reservation budget.
-rw-r--r-- | litmus/polling_reservations.c | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/litmus/polling_reservations.c b/litmus/polling_reservations.c index e6c57f592780..5c9b1832d2d9 100644 --- a/litmus/polling_reservations.c +++ b/litmus/polling_reservations.c | |||
@@ -361,11 +361,6 @@ static void td_client_departs( | |||
361 | } | 361 | } |
362 | } | 362 | } |
363 | 363 | ||
364 | static lt_t td_interval_length(struct lt_interval *ival) | ||
365 | { | ||
366 | return ival->end - ival->start; | ||
367 | } | ||
368 | |||
369 | static lt_t td_time_remaining_until_end(struct table_driven_reservation *tdres) | 364 | static lt_t td_time_remaining_until_end(struct table_driven_reservation *tdres) |
370 | { | 365 | { |
371 | lt_t now = tdres->res.env->current_time; | 366 | lt_t now = tdres->res.env->current_time; |
@@ -388,7 +383,9 @@ static void td_replenish( | |||
388 | 383 | ||
389 | /* replenish budget */ | 384 | /* replenish budget */ |
390 | tdres->cur_interval = tdres->intervals + tdres->next_interval; | 385 | tdres->cur_interval = tdres->intervals + tdres->next_interval; |
391 | res->cur_budget = td_interval_length(tdres->cur_interval); | 386 | res->cur_budget = td_time_remaining_until_end(tdres); |
387 | TRACE("td_replenish(%u): %s budget=%llu\n", res->id, | ||
388 | res->cur_budget ? "" : "WARNING", res->cur_budget); | ||
392 | 389 | ||
393 | tdres->next_interval = (tdres->next_interval + 1) % tdres->num_intervals; | 390 | tdres->next_interval = (tdres->next_interval + 1) % tdres->num_intervals; |
394 | if (tdres->next_interval) | 391 | if (tdres->next_interval) |
@@ -447,10 +444,44 @@ static void td_drain_budget( | |||
447 | } | 444 | } |
448 | } | 445 | } |
449 | 446 | ||
447 | static struct task_struct* td_dispatch_client( | ||
448 | struct reservation *res, | ||
449 | lt_t *for_at_most) | ||
450 | { | ||
451 | struct task_struct *t; | ||
452 | struct table_driven_reservation *tdres = | ||
453 | container_of(res, struct table_driven_reservation, res); | ||
450 | 454 | ||
455 | /* usual logic for selecting a client */ | ||
456 | t = default_dispatch_client(res, for_at_most); | ||
457 | |||
458 | TRACE_TASK(t, "td_dispatch_client(%u): selected, budget=%llu\n", | ||
459 | res->id, res->cur_budget); | ||
460 | |||
461 | /* check how much budget we have left in this time slot */ | ||
462 | res->cur_budget = td_time_remaining_until_end(tdres); | ||
463 | |||
464 | TRACE_TASK(t, "td_dispatch_client(%u): updated to budget=%llu next=%d\n", | ||
465 | res->id, res->cur_budget, tdres->next_interval); | ||
466 | |||
467 | if (unlikely(!res->cur_budget)) { | ||
468 | /* Unlikely case: if we ran out of budget, the user configured | ||
469 | * a broken scheduling table (overlapping table slots). | ||
470 | * Not much we can do about this, but we can't dispatch a job | ||
471 | * now without causing overload. So let's register this reservation | ||
472 | * as depleted and wait for the next allocation. */ | ||
473 | TRACE("td_dispatch_client(%u): budget unexpectedly depleted " | ||
474 | "(check scheduling table for unintended overlap)\n", | ||
475 | res->id); | ||
476 | res->env->change_state(res->env, res, | ||
477 | RESERVATION_DEPLETED); | ||
478 | return NULL; | ||
479 | } else | ||
480 | return t; | ||
481 | } | ||
451 | 482 | ||
452 | static struct reservation_ops td_ops = { | 483 | static struct reservation_ops td_ops = { |
453 | .dispatch_client = default_dispatch_client, | 484 | .dispatch_client = td_dispatch_client, |
454 | .client_arrives = td_client_arrives, | 485 | .client_arrives = td_client_arrives, |
455 | .client_departs = td_client_departs, | 486 | .client_departs = td_client_departs, |
456 | .replenish = td_replenish, | 487 | .replenish = td_replenish, |