aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhoon Kim <namhoonk@cs.unc.edu>2015-01-24 13:24:12 -0500
committerNamhoon Kim <namhoonk@cs.unc.edu>2015-01-24 13:24:12 -0500
commitca538aafd7cebfd09a47af0a628647620a6bba35 (patch)
tree811e8a0663e5eda924fa68ef2a5a104501c1cdfa
parent34fe51ed2dc210e87bfa5d85ab98c5125495f002 (diff)
Reservation destroy
-rw-r--r--include/litmus/reservation.h8
-rw-r--r--litmus/polling_reservations.c1
-rw-r--r--litmus/reservation.c6
-rw-r--r--litmus/sched_mc2.c47
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
134void reservation_init(struct reservation *res); 136void 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
229void gmp_init(struct gmp_reservation_environment* gmp_env); 231void gmp_init(struct gmp_reservation_environment* gmp_env);
230void gmp_add_new_reservation(struct gmp_reservation_environment* gmp_env, 232void gmp_add_new_reservation(struct gmp_reservation_environment* gmp_env,
231 struct reservation* new_res); 233 struct reservation* new_res);
232void gmp_update_time(struct gmp_reservation_environment* gmp_env, lt_t now); 234void gmp_update_time(struct gmp_reservation_environment* gmp_env, lt_t now);
233struct task_struct* gmp_dispatch(struct gmp_reservation_environment* gmp_env); 235struct task_struct* gmp_dispatch(struct gmp_reservation_environment* gmp_env);
234 236struct next_timer_event* gmp_find_event_by_id(struct gmp_reservation_environment* gmp_env, unsigned int id);
235struct reservation* gmp_find_by_id(struct gmp_reservation_environment* gmp_env, 237struct 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
89static void task_arrives(struct task_struct *tsk) 89static 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
275static struct task_struct* mc2_schedule(struct task_struct * prev) 291static 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 {