diff options
author | Namhoon Kim <namhoonk@cs.unc.edu> | 2015-01-24 13:24:12 -0500 |
---|---|---|
committer | Namhoon Kim <namhoonk@cs.unc.edu> | 2015-01-24 13:24:12 -0500 |
commit | ca538aafd7cebfd09a47af0a628647620a6bba35 (patch) | |
tree | 811e8a0663e5eda924fa68ef2a5a104501c1cdfa | |
parent | 34fe51ed2dc210e87bfa5d85ab98c5125495f002 (diff) |
Reservation destroy
-rw-r--r-- | include/litmus/reservation.h | 8 | ||||
-rw-r--r-- | litmus/polling_reservations.c | 1 | ||||
-rw-r--r-- | litmus/reservation.c | 6 | ||||
-rw-r--r-- | litmus/sched_mc2.c | 47 |
4 files changed, 50 insertions, 12 deletions
diff --git a/include/litmus/reservation.h b/include/litmus/reservation.h index 5ccb20055a56..0e656ad2667e 100644 --- a/include/litmus/reservation.h +++ b/include/litmus/reservation.h | |||
@@ -129,6 +129,8 @@ struct reservation { | |||
129 | 129 | ||
130 | /* for global env. */ | 130 | /* for global env. */ |
131 | int scheduled_on; | 131 | int scheduled_on; |
132 | /* for blocked by ghost */ | ||
133 | int blocked_by_ghost; | ||
132 | }; | 134 | }; |
133 | 135 | ||
134 | void reservation_init(struct reservation *res); | 136 | void reservation_init(struct reservation *res); |
@@ -225,14 +227,14 @@ struct gmp_reservation_environment { | |||
225 | /* set to true if a call to gmp_dispatch() is imminent */ | 227 | /* set to true if a call to gmp_dispatch() is imminent */ |
226 | bool will_schedule; | 228 | bool will_schedule; |
227 | }; | 229 | }; |
228 | /* | 230 | |
229 | void gmp_init(struct gmp_reservation_environment* gmp_env); | 231 | void gmp_init(struct gmp_reservation_environment* gmp_env); |
230 | void gmp_add_new_reservation(struct gmp_reservation_environment* gmp_env, | 232 | void gmp_add_new_reservation(struct gmp_reservation_environment* gmp_env, |
231 | struct reservation* new_res); | 233 | struct reservation* new_res); |
232 | void gmp_update_time(struct gmp_reservation_environment* gmp_env, lt_t now); | 234 | void gmp_update_time(struct gmp_reservation_environment* gmp_env, lt_t now); |
233 | struct task_struct* gmp_dispatch(struct gmp_reservation_environment* gmp_env); | 235 | struct task_struct* gmp_dispatch(struct gmp_reservation_environment* gmp_env); |
234 | 236 | struct next_timer_event* gmp_find_event_by_id(struct gmp_reservation_environment* gmp_env, unsigned int id); | |
235 | struct reservation* gmp_find_by_id(struct gmp_reservation_environment* gmp_env, | 237 | struct reservation* gmp_find_by_id(struct gmp_reservation_environment* gmp_env, |
236 | unsigned int id); | 238 | unsigned int id); |
237 | */ | 239 | |
238 | #endif | 240 | #endif |
diff --git a/litmus/polling_reservations.c b/litmus/polling_reservations.c index 941a371c26e9..ec5cadd19b4f 100644 --- a/litmus/polling_reservations.c +++ b/litmus/polling_reservations.c | |||
@@ -46,6 +46,7 @@ static void periodic_polling_client_arrives( | |||
46 | break; | 46 | break; |
47 | 47 | ||
48 | case RESERVATION_ACTIVE_IDLE: | 48 | case RESERVATION_ACTIVE_IDLE: |
49 | res->blocked_by_ghost = 0; | ||
49 | res->env->change_state(res->env, res, | 50 | res->env->change_state(res->env, res, |
50 | RESERVATION_ACTIVE); | 51 | RESERVATION_ACTIVE); |
51 | break; | 52 | break; |
diff --git a/litmus/reservation.c b/litmus/reservation.c index 2dc3dc2b4688..16b3a4818e1e 100644 --- a/litmus/reservation.c +++ b/litmus/reservation.c | |||
@@ -194,9 +194,11 @@ static void sup_charge_budget( | |||
194 | res = list_entry(pos, struct reservation, list); | 194 | res = list_entry(pos, struct reservation, list); |
195 | if (res->state == RESERVATION_ACTIVE) { | 195 | if (res->state == RESERVATION_ACTIVE) { |
196 | TRACE("sup_charge_budget ACTIVE R%u drain %llu\n", res->id, delta); | 196 | TRACE("sup_charge_budget ACTIVE R%u drain %llu\n", res->id, delta); |
197 | if (encountered_active == 0) | 197 | if (encountered_active == 0 && res->blocked_by_ghost == 0) { |
198 | TRACE("DRAIN !!\n"); | ||
198 | res->ops->drain_budget(res, delta); | 199 | res->ops->drain_budget(res, delta); |
199 | encountered_active = 1; | 200 | encountered_active = 1; |
201 | } | ||
200 | } else { | 202 | } else { |
201 | BUG_ON(res->state != RESERVATION_ACTIVE_IDLE); | 203 | BUG_ON(res->state != RESERVATION_ACTIVE_IDLE); |
202 | TRACE("sup_charge_budget INACTIVE R%u drain %llu\n", res->id, delta); | 204 | TRACE("sup_charge_budget INACTIVE R%u drain %llu\n", res->id, delta); |
diff --git a/litmus/sched_mc2.c b/litmus/sched_mc2.c index 499f770a87d3..0c260190f287 100644 --- a/litmus/sched_mc2.c +++ b/litmus/sched_mc2.c | |||
@@ -86,17 +86,25 @@ static void task_departs(struct task_struct *tsk, int job_complete) | |||
86 | } | 86 | } |
87 | } | 87 | } |
88 | 88 | ||
89 | static void task_arrives(struct task_struct *tsk) | 89 | static void task_arrives(struct mc2_cpu_state *state, struct task_struct *tsk) |
90 | { | 90 | { |
91 | struct mc2_task_state* tinfo = get_mc2_state(tsk); | 91 | struct mc2_task_state* tinfo = get_mc2_state(tsk); |
92 | struct reservation* res; | 92 | struct reservation* res; |
93 | struct reservation_client *client; | 93 | struct reservation_client *client; |
94 | enum crit_level lv = get_task_crit_level(tsk); | ||
94 | 95 | ||
95 | res = tinfo->res_info.client.reservation; | 96 | res = tinfo->res_info.client.reservation; |
96 | client = &tinfo->res_info.client; | 97 | client = &tinfo->res_info.client; |
97 | 98 | ||
98 | tinfo->has_departed = false; | 99 | tinfo->has_departed = false; |
99 | res->ops->client_arrives(res, client); | 100 | res->ops->client_arrives(res, client); |
101 | |||
102 | if (lv != NUM_CRIT_LEVELS) { | ||
103 | struct crit_entry *ce; | ||
104 | ce = &state->crit_entries[lv]; | ||
105 | if (ce->running == tsk) | ||
106 | ce->running = NULL; | ||
107 | } | ||
100 | } | 108 | } |
101 | 109 | ||
102 | /* NOTE: drops state->lock */ | 110 | /* NOTE: drops state->lock */ |
@@ -174,8 +182,13 @@ static void mc2_update_ghost_state(struct mc2_cpu_state *state) | |||
174 | continue; | 182 | continue; |
175 | TRACE("LV %d running id %d budget %llu\n", lv, tinfo->mc2_param.res_id, res->cur_budget); | 183 | TRACE("LV %d running id %d budget %llu\n", lv, tinfo->mc2_param.res_id, res->cur_budget); |
176 | if (!res->cur_budget) { | 184 | if (!res->cur_budget) { |
185 | struct sup_reservation_environment* sup_env = &state->sup_env; | ||
186 | |||
177 | TRACE("GHOST FINISH id %d at %llu\n", tinfo->mc2_param.res_id, litmus_clock()); | 187 | TRACE("GHOST FINISH id %d at %llu\n", tinfo->mc2_param.res_id, litmus_clock()); |
178 | ce->running = NULL; | 188 | ce->running = NULL; |
189 | res = list_first_entry_or_null(&sup_env->active_reservations, struct reservation, list); | ||
190 | if (res) | ||
191 | litmus_reschedule_local(); | ||
179 | } | 192 | } |
180 | } | 193 | } |
181 | } | 194 | } |
@@ -262,7 +275,10 @@ struct task_struct* mc2_dispatch(struct sup_reservation_environment* sup_env, st | |||
262 | ce = &state->crit_entries[lv]; | 275 | ce = &state->crit_entries[lv]; |
263 | if (likely(!ce->running)) { | 276 | if (likely(!ce->running)) { |
264 | sup_scheduler_update_after(sup_env, res->cur_budget); | 277 | sup_scheduler_update_after(sup_env, res->cur_budget); |
278 | res->blocked_by_ghost = 0; | ||
265 | return tsk; | 279 | return tsk; |
280 | } else { | ||
281 | res->blocked_by_ghost = 1; | ||
266 | } | 282 | } |
267 | } | 283 | } |
268 | } | 284 | } |
@@ -275,7 +291,6 @@ struct task_struct* mc2_dispatch(struct sup_reservation_environment* sup_env, st | |||
275 | static struct task_struct* mc2_schedule(struct task_struct * prev) | 291 | static struct task_struct* mc2_schedule(struct task_struct * prev) |
276 | { | 292 | { |
277 | /* next == NULL means "schedule background work". */ | 293 | /* next == NULL means "schedule background work". */ |
278 | struct mc2_task_state *tinfo; | ||
279 | struct mc2_cpu_state *state = local_cpu_state(); | 294 | struct mc2_cpu_state *state = local_cpu_state(); |
280 | 295 | ||
281 | raw_spin_lock(&state->lock); | 296 | raw_spin_lock(&state->lock); |
@@ -352,7 +367,7 @@ static void mc2_task_resume(struct task_struct *tsk) | |||
352 | * at the moment. */ | 367 | * at the moment. */ |
353 | sup_update_time(&state->sup_env, litmus_clock()); | 368 | sup_update_time(&state->sup_env, litmus_clock()); |
354 | mc2_update_ghost_state(state); | 369 | mc2_update_ghost_state(state); |
355 | task_arrives(tsk); | 370 | task_arrives(state, tsk); |
356 | /* NOTE: drops state->lock */ | 371 | /* NOTE: drops state->lock */ |
357 | TRACE_TASK(tsk, "mc2_resume()\n"); | 372 | TRACE_TASK(tsk, "mc2_resume()\n"); |
358 | mc2_update_timer_and_unlock(state); | 373 | mc2_update_timer_and_unlock(state); |
@@ -498,7 +513,7 @@ static void mc2_task_new(struct task_struct *tsk, int on_runqueue, | |||
498 | * [see comment in pres_task_resume()] */ | 513 | * [see comment in pres_task_resume()] */ |
499 | sup_update_time(&state->sup_env, litmus_clock()); | 514 | sup_update_time(&state->sup_env, litmus_clock()); |
500 | mc2_update_ghost_state(state); | 515 | mc2_update_ghost_state(state); |
501 | task_arrives(tsk); | 516 | task_arrives(state, tsk); |
502 | /* NOTE: drops state->lock */ | 517 | /* NOTE: drops state->lock */ |
503 | TRACE("mc2_new()\n"); | 518 | TRACE("mc2_new()\n"); |
504 | mc2_update_timer_and_unlock(state); | 519 | mc2_update_timer_and_unlock(state); |
@@ -521,6 +536,7 @@ static long mc2_reservation_destroy(unsigned int reservation_id, int cpu) | |||
521 | struct reservation *res = NULL, *next; | 536 | struct reservation *res = NULL, *next; |
522 | struct sup_reservation_environment *sup_env; | 537 | struct sup_reservation_environment *sup_env; |
523 | int found = 0; | 538 | int found = 0; |
539 | enum crit_level lv = get_task_crit_level(current); | ||
524 | 540 | ||
525 | state = cpu_state_for(cpu); | 541 | state = cpu_state_for(cpu); |
526 | raw_spin_lock(&state->lock); | 542 | raw_spin_lock(&state->lock); |
@@ -530,8 +546,13 @@ static long mc2_reservation_destroy(unsigned int reservation_id, int cpu) | |||
530 | //if (!res) { | 546 | //if (!res) { |
531 | list_for_each_entry_safe(res, next, &sup_env->depleted_reservations, list) { | 547 | list_for_each_entry_safe(res, next, &sup_env->depleted_reservations, list) { |
532 | if (res->id == reservation_id) { | 548 | if (res->id == reservation_id) { |
549 | if (lv == CRIT_LEVEL_A) { | ||
550 | struct table_driven_reservation *tdres; | ||
551 | tdres = container_of(res, struct table_driven_reservation, res); | ||
552 | kfree(tdres->intervals); | ||
553 | } | ||
533 | list_del(&res->list); | 554 | list_del(&res->list); |
534 | //kfree(res); | 555 | kfree(res); |
535 | found = 1; | 556 | found = 1; |
536 | ret = 0; | 557 | ret = 0; |
537 | } | 558 | } |
@@ -539,8 +560,13 @@ static long mc2_reservation_destroy(unsigned int reservation_id, int cpu) | |||
539 | if (!found) { | 560 | if (!found) { |
540 | list_for_each_entry_safe(res, next, &sup_env->inactive_reservations, list) { | 561 | list_for_each_entry_safe(res, next, &sup_env->inactive_reservations, list) { |
541 | if (res->id == reservation_id) { | 562 | if (res->id == reservation_id) { |
563 | if (lv == CRIT_LEVEL_A) { | ||
564 | struct table_driven_reservation *tdres; | ||
565 | tdres = container_of(res, struct table_driven_reservation, res); | ||
566 | kfree(tdres->intervals); | ||
567 | } | ||
542 | list_del(&res->list); | 568 | list_del(&res->list); |
543 | //kfree(res); | 569 | kfree(res); |
544 | found = 1; | 570 | found = 1; |
545 | ret = 0; | 571 | ret = 0; |
546 | } | 572 | } |
@@ -549,8 +575,13 @@ static long mc2_reservation_destroy(unsigned int reservation_id, int cpu) | |||
549 | if (!found) { | 575 | if (!found) { |
550 | list_for_each_entry_safe(res, next, &sup_env->active_reservations, list) { | 576 | list_for_each_entry_safe(res, next, &sup_env->active_reservations, list) { |
551 | if (res->id == reservation_id) { | 577 | if (res->id == reservation_id) { |
578 | if (lv == CRIT_LEVEL_A) { | ||
579 | struct table_driven_reservation *tdres; | ||
580 | tdres = container_of(res, struct table_driven_reservation, res); | ||
581 | kfree(tdres->intervals); | ||
582 | } | ||
552 | list_del(&res->list); | 583 | list_del(&res->list); |
553 | //kfree(res); | 584 | kfree(res); |
554 | found = 1; | 585 | found = 1; |
555 | ret = 0; | 586 | ret = 0; |
556 | } | 587 | } |
@@ -665,6 +696,7 @@ static long create_polling_reservation( | |||
665 | config->polling_params.relative_deadline, | 696 | config->polling_params.relative_deadline, |
666 | config->polling_params.offset); | 697 | config->polling_params.offset); |
667 | pres->res.id = config->id; | 698 | pres->res.id = config->id; |
699 | pres->res.blocked_by_ghost = 0; | ||
668 | if (!use_edf) | 700 | if (!use_edf) |
669 | pres->res.priority = config->priority; | 701 | pres->res.priority = config->priority; |
670 | sup_add_new_reservation(&state->sup_env, &pres->res); | 702 | sup_add_new_reservation(&state->sup_env, &pres->res); |
@@ -765,6 +797,7 @@ static long create_table_driven_reservation( | |||
765 | slots, num_slots); | 797 | slots, num_slots); |
766 | td_res->res.id = config->id; | 798 | td_res->res.id = config->id; |
767 | td_res->res.priority = config->priority; | 799 | td_res->res.priority = config->priority; |
800 | td_res->res.blocked_by_ghost = 0; | ||
768 | sup_add_new_reservation(&state->sup_env, &td_res->res); | 801 | sup_add_new_reservation(&state->sup_env, &td_res->res); |
769 | err = config->id; | 802 | err = config->id; |
770 | } else { | 803 | } else { |