diff options
| author | Zelin Tong <ztong@ludwig.cs.unc.edu> | 2020-03-04 13:54:43 -0500 |
|---|---|---|
| committer | Zelin Tong <ztong@ludwig.cs.unc.edu> | 2020-03-04 13:54:43 -0500 |
| commit | ade4ca95d6619e92b348259395a30d978842a77a (patch) | |
| tree | 943dcc02954e3e57f642dfca2e737982cc4bab37 | |
| parent | a3591651158fb7839bf5b7a84620d5f3fe31f326 (diff) | |
| parent | 1f4fabf52690ef8f84275b720b25e7a0adc74440 (diff) | |
Merge branch 'edfsc-wip' of rtsrv.cs.unc.edu:/public/litmus-rt-edfsc into edfsc-wip
| -rw-r--r-- | litmus/sched_edfsc.c | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/litmus/sched_edfsc.c b/litmus/sched_edfsc.c index 14a775453a78..ea1b308667c7 100644 --- a/litmus/sched_edfsc.c +++ b/litmus/sched_edfsc.c | |||
| @@ -1001,52 +1001,72 @@ static void edfsc_task_block(struct task_struct *t) | |||
| 1001 | // TODO | 1001 | // TODO |
| 1002 | } | 1002 | } |
| 1003 | 1003 | ||
| 1004 | /** | ||
| 1005 | * This is called by LITMUS before our task is switched to another scheduler | ||
| 1006 | * During task termination (do_exit()), LITMUS first switches the scheduler | ||
| 1007 | * to SCHED_FIFO before running the normal Linux task termination proceedure. | ||
| 1008 | * After we return from this, `t` may or may not still exist. So we should have | ||
| 1009 | * no outstanding handles to any part of the task struct afer this point. | ||
| 1010 | */ | ||
| 1004 | static void edfsc_task_exit(struct task_struct* t) | 1011 | static void edfsc_task_exit(struct task_struct* t) |
| 1005 | { | 1012 | { |
| 1006 | unsigned long flags; | 1013 | unsigned long flags; |
| 1007 | lt_t now; | 1014 | lt_t now, unaccount_time = 0; |
| 1008 | raw_spin_lock_irqsave(&g_lock, flags); | 1015 | cpu_entry_t* entry; |
| 1009 | now = litmus_clock(); | 1016 | |
| 1010 | 1017 | ||
| 1018 | BUG_ON(is_container(t)); | ||
| 1019 | raw_spin_lock_irqsave(&g_lock, flags); | ||
| 1020 | // XXX: Superfluous. We never see `t` as one of our tasks again. | ||
| 1011 | tsk_rt(t)->edfsc_params.will_remove = 1; | 1021 | tsk_rt(t)->edfsc_params.will_remove = 1; |
| 1012 | 1022 | ||
| 1013 | // If the task has no pending job | 1023 | |
| 1014 | if (!is_released(t, now)) { | 1024 | // Remove this task from all members of its scheduling domain |
| 1015 | // If the deadline of its last job is in the future, reserve the | 1025 | unlink(t); |
| 1016 | // utilization until its deadline | 1026 | if (is_queued(t)) { |
| 1017 | if (lt_after(tsk_rt(t)->edfsc_params.prev_deadline, now)) { | 1027 | remove(tsk_rt(t)->domain, t); |
| 1018 | if (is_queued(t)) | 1028 | } else if (is_fixed(t)) { |
| 1019 | remove(tsk_rt(t)->domain, t); | 1029 | // If we're fixed and not on the ready queues, we should be currently running |
| 1020 | //hrtimer_start(&(tsk_rt(t)->edfsc_params.deadline_timer), | 1030 | BUG_ON(((cont_domain_t*)tsk_rt(t)->domain)->scheduled != t); |
| 1021 | // ns_to_ktime(tsk_rt(t)->edfsc_params.prev_deadline), | 1031 | BUG_ON(t != current); |
| 1022 | // HRTIMER_MODE_ABS_PINNED); | 1032 | ((cont_domain_t*)tsk_rt(t)->domain)->scheduled = NULL; |
| 1023 | hrtimer_start(&t->edfsc_deadline_timer, | ||
| 1024 | ns_to_ktime(tsk_rt(t)->edfsc_params.prev_deadline), | ||
| 1025 | HRTIMER_MODE_ABS_PINNED); | ||
| 1026 | // Else remove it and we're done | ||
| 1027 | } else { | ||
| 1028 | if (is_queued(t)) | ||
| 1029 | remove(tsk_rt(t)->domain, t); | ||
| 1030 | // XXX not sure if this needs an additional condition guarding it | ||
| 1031 | remove_task(t); | ||
| 1032 | } | ||
| 1033 | // If the task has a pending job, we can immediatly stop LITMUS from | ||
| 1034 | // scheduling it but still have to reserve its utilization until the deadline | ||
| 1035 | } else { | 1033 | } else { |
| 1036 | //reserve the utilization, but remove it from being scheduled by litmus | 1034 | // We're in the global domain and not on the ready queues, so we must be running |
| 1037 | unlink(t); | 1035 | BUG_ON(t != current); |
| 1038 | if (tsk_rt(t)->scheduled_on != NO_CPU) { | 1036 | BUG_ON(tsk_rt(t)->scheduled_on == NO_CPU); |
| 1039 | (&per_cpu(edfsc_cpu_entries, tsk_rt(t)->scheduled_on))->scheduled = NULL; | 1037 | entry = &per_cpu(edfsc_cpu_entries, tsk_rt(t)->scheduled_on); |
| 1040 | tsk_rt(t)->scheduled_on = NO_CPU; | 1038 | BUG_ON(entry->scheduled != t); |
| 1041 | } | 1039 | entry->scheduled = NULL; |
| 1042 | //hrtimer_start(&(tsk_rt(t)->edfsc_params.deadline_timer), | 1040 | } |
| 1043 | // ns_to_ktime(get_deadline(t)), | 1041 | |
| 1044 | // HRTIMER_MODE_ABS_PINNED); | 1042 | /* To preserve EDF-sc scheduling invariants, we can only release a task's |
| 1045 | hrtimer_start(&t->edfsc_deadline_timer, | 1043 | * utilization at the greater of the period or deadline boundry. Thus, here |
| 1046 | ns_to_ktime(get_deadline(t)), | 1044 | * we schedule a timer to handle this unaccounting of utilization. |
| 1047 | HRTIMER_MODE_ABS_PINNED); | 1045 | */ |
| 1046 | now = litmus_clock(); | ||
| 1047 | if (is_released(t, now)) { | ||
| 1048 | /* If a task has already been released, no future jobs are pending and we can | ||
| 1049 | * just unaccount at the current deadline. | ||
| 1050 | */ | ||
| 1051 | unaccount_time = get_deadline(t); | ||
| 1052 | } else { | ||
| 1053 | /* If the task has yet to be released, but we still haven't reached the | ||
| 1054 | * deadline of its last-finished job, wait for that deadline. Otherwise | ||
| 1055 | * we're after a deadline and before a release, so just remove now. | ||
| 1056 | */ | ||
| 1057 | if (lt_after(tsk_rt(t)->edfsc_params.prev_deadline, now)) | ||
| 1058 | unaccount_time = tsk_rt(t)->edfsc_params.prev_deadline; | ||
| 1059 | else | ||
| 1060 | unaccount_time = 0; | ||
| 1048 | } | 1061 | } |
| 1049 | 1062 | ||
| 1063 | if (unaccount_time == 0) | ||
| 1064 | remove_task(t); | ||
| 1065 | else | ||
| 1066 | // FIXME: This timer uses task struct data that may or may not exist at expiration | ||
| 1067 | hrtimer_start(&t->edfsc_deadline_timer, ns_to_ktime(unaccount_time), | ||
| 1068 | HRTIMER_MODE_ABS_PINNED); | ||
| 1069 | |||
| 1050 | raw_spin_unlock_irqrestore(&g_lock, flags); | 1070 | raw_spin_unlock_irqrestore(&g_lock, flags); |
| 1051 | } | 1071 | } |
| 1052 | 1072 | ||
