diff options
-rw-r--r-- | include/litmus/budget.h | 2 | ||||
-rw-r--r-- | include/litmus/sched_plugin.h | 9 | ||||
-rw-r--r-- | litmus/budget.c | 52 | ||||
-rw-r--r-- | litmus/sched_plugin.c | 4 |
4 files changed, 67 insertions, 0 deletions
diff --git a/include/litmus/budget.h b/include/litmus/budget.h index bd2d5c964f92..60eb814fc82b 100644 --- a/include/litmus/budget.h +++ b/include/litmus/budget.h | |||
@@ -33,4 +33,6 @@ static inline int requeue_preempted_job(struct task_struct* t) | |||
33 | (!budget_exhausted(t) || !budget_enforced(t)); | 33 | (!budget_exhausted(t) || !budget_enforced(t)); |
34 | } | 34 | } |
35 | 35 | ||
36 | void litmus_current_budget(lt_t *used_so_far, lt_t *remaining); | ||
37 | |||
36 | #endif | 38 | #endif |
diff --git a/include/litmus/sched_plugin.h b/include/litmus/sched_plugin.h index 0ccccd6ae1af..f36bb3875f58 100644 --- a/include/litmus/sched_plugin.h +++ b/include/litmus/sched_plugin.h | |||
@@ -77,6 +77,13 @@ typedef long (*wait_for_release_at_t)(lt_t release_time); | |||
77 | /* Informs the plugin when a synchronous release takes place. */ | 77 | /* Informs the plugin when a synchronous release takes place. */ |
78 | typedef void (*synchronous_release_at_t)(lt_t time_zero); | 78 | typedef void (*synchronous_release_at_t)(lt_t time_zero); |
79 | 79 | ||
80 | /* How much budget has the current task consumed so far, and how much | ||
81 | * has it left? The default implementation ties into the per-task | ||
82 | * budget enforcement code. Plugins can override this to report | ||
83 | * reservation-specific values. */ | ||
84 | typedef void (*current_budget_t)(lt_t *used_so_far, lt_t *remaining); | ||
85 | |||
86 | |||
80 | /************************ misc routines ***********************/ | 87 | /************************ misc routines ***********************/ |
81 | 88 | ||
82 | 89 | ||
@@ -109,6 +116,8 @@ struct sched_plugin { | |||
109 | task_exit_t task_exit; | 116 | task_exit_t task_exit; |
110 | task_cleanup_t task_cleanup; | 117 | task_cleanup_t task_cleanup; |
111 | 118 | ||
119 | current_budget_t current_budget; | ||
120 | |||
112 | #ifdef CONFIG_LITMUS_LOCKING | 121 | #ifdef CONFIG_LITMUS_LOCKING |
113 | /* locking protocols */ | 122 | /* locking protocols */ |
114 | allocate_lock_t allocate_lock; | 123 | allocate_lock_t allocate_lock; |
diff --git a/litmus/budget.c b/litmus/budget.c index 47bf78a19f87..d67f4b387862 100644 --- a/litmus/budget.c +++ b/litmus/budget.c | |||
@@ -1,9 +1,11 @@ | |||
1 | #include <linux/sched.h> | 1 | #include <linux/sched.h> |
2 | #include <linux/percpu.h> | 2 | #include <linux/percpu.h> |
3 | #include <linux/hrtimer.h> | 3 | #include <linux/hrtimer.h> |
4 | #include <linux/uaccess.h> | ||
4 | 5 | ||
5 | #include <litmus/litmus.h> | 6 | #include <litmus/litmus.h> |
6 | #include <litmus/preempt.h> | 7 | #include <litmus/preempt.h> |
8 | #include <litmus/sched_plugin.h> | ||
7 | 9 | ||
8 | #include <litmus/budget.h> | 10 | #include <litmus/budget.h> |
9 | 11 | ||
@@ -113,4 +115,54 @@ static int __init init_budget_enforcement(void) | |||
113 | return 0; | 115 | return 0; |
114 | } | 116 | } |
115 | 117 | ||
118 | void litmus_current_budget(lt_t *used_so_far, lt_t *remaining) | ||
119 | { | ||
120 | struct task_struct *t = current; | ||
121 | unsigned long flags; | ||
122 | s64 delta; | ||
123 | |||
124 | local_irq_save(flags); | ||
125 | |||
126 | delta = sched_clock_cpu(smp_processor_id()) - t->se.exec_start; | ||
127 | if (delta < 0) | ||
128 | delta = 0; | ||
129 | |||
130 | TRACE_CUR("current_budget: sc:%llu start:%llu lt_t:%llu delta:%lld exec-time:%llu rem:%llu\n", | ||
131 | sched_clock_cpu(smp_processor_id()), t->se.exec_start, | ||
132 | litmus_clock(), delta, | ||
133 | tsk_rt(t)->job_params.exec_time, | ||
134 | budget_remaining(t)); | ||
135 | |||
136 | if (used_so_far) | ||
137 | *used_so_far = tsk_rt(t)->job_params.exec_time + delta; | ||
138 | |||
139 | if (remaining) { | ||
140 | *remaining = budget_remaining(t); | ||
141 | if (*remaining > delta) | ||
142 | *remaining -= delta; | ||
143 | else | ||
144 | *remaining = 0; | ||
145 | } | ||
146 | |||
147 | local_irq_restore(flags); | ||
148 | } | ||
149 | |||
150 | asmlinkage long sys_get_current_budget( | ||
151 | lt_t __user * _expended, | ||
152 | lt_t __user *_remaining) | ||
153 | { | ||
154 | lt_t expended = 0, remaining = 0; | ||
155 | |||
156 | if (is_realtime(current)) | ||
157 | litmus->current_budget(&expended, &remaining); | ||
158 | |||
159 | if (_expended && put_user(expended, _expended)) | ||
160 | return -EFAULT; | ||
161 | |||
162 | if (_remaining && put_user(remaining, _remaining)) | ||
163 | return -EFAULT; | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
116 | module_init(init_budget_enforcement); | 168 | module_init(init_budget_enforcement); |
diff --git a/litmus/sched_plugin.c b/litmus/sched_plugin.c index edd91e9bf773..7b1eba0de75c 100644 --- a/litmus/sched_plugin.c +++ b/litmus/sched_plugin.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <litmus/sched_plugin.h> | 13 | #include <litmus/sched_plugin.h> |
14 | #include <litmus/preempt.h> | 14 | #include <litmus/preempt.h> |
15 | #include <litmus/jobs.h> | 15 | #include <litmus/jobs.h> |
16 | #include <litmus/budget.h> | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * Generic function to trigger preemption on either local or remote cpu | 19 | * Generic function to trigger preemption on either local or remote cpu |
@@ -197,6 +198,9 @@ int register_sched_plugin(struct sched_plugin* plugin) | |||
197 | if (!plugin->wait_for_release_at) | 198 | if (!plugin->wait_for_release_at) |
198 | plugin->wait_for_release_at = default_wait_for_release_at; | 199 | plugin->wait_for_release_at = default_wait_for_release_at; |
199 | 200 | ||
201 | if (!plugin->current_budget) | ||
202 | plugin->current_budget = litmus_current_budget; | ||
203 | |||
200 | raw_spin_lock(&sched_plugins_lock); | 204 | raw_spin_lock(&sched_plugins_lock); |
201 | list_add(&plugin->list, &sched_plugins); | 205 | list_add(&plugin->list, &sched_plugins); |
202 | raw_spin_unlock(&sched_plugins_lock); | 206 | raw_spin_unlock(&sched_plugins_lock); |