diff options
-rw-r--r-- | include/litmus/pgm.h | 11 | ||||
-rw-r--r-- | litmus/Makefile | 1 | ||||
-rw-r--r-- | litmus/pgm.c | 54 |
3 files changed, 66 insertions, 0 deletions
diff --git a/include/litmus/pgm.h b/include/litmus/pgm.h new file mode 100644 index 000000000000..1e87e170e8c3 --- /dev/null +++ b/include/litmus/pgm.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef _LITMUS_PGM_H_ | ||
2 | #define _LITMUS_PGM_H_ | ||
3 | |||
4 | #include <litmus/litmus.h> | ||
5 | |||
6 | #define is_pgm_waiting(t) (tsk_rt(t)->ctrl_page && tsk_rt(t)->ctrl_page->pgm_waiting) | ||
7 | #define is_pgm_satisfied(t) (tsk_rt(t)->ctrl_page && tsk_rt(t)->ctrl_page->pgm_satisfied) | ||
8 | |||
9 | void setup_pgm_release(struct task_struct* t); | ||
10 | |||
11 | #endif | ||
diff --git a/litmus/Makefile b/litmus/Makefile index 2bddc94a399f..52f407cad77c 100644 --- a/litmus/Makefile +++ b/litmus/Makefile | |||
@@ -26,6 +26,7 @@ obj-y = sched_plugin.o litmus.o \ | |||
26 | obj-$(CONFIG_PLUGIN_CEDF) += sched_cedf.o | 26 | obj-$(CONFIG_PLUGIN_CEDF) += sched_cedf.o |
27 | obj-$(CONFIG_PLUGIN_PFAIR) += sched_pfair.o | 27 | obj-$(CONFIG_PLUGIN_PFAIR) += sched_pfair.o |
28 | obj-$(CONFIG_SCHED_CPU_AFFINITY) += affinity.o | 28 | obj-$(CONFIG_SCHED_CPU_AFFINITY) += affinity.o |
29 | obj-$(CONFIG_SCHED_PGM) += pgm.o | ||
29 | 30 | ||
30 | obj-$(CONFIG_FEATHER_TRACE) += ft_event.o ftdev.o | 31 | obj-$(CONFIG_FEATHER_TRACE) += ft_event.o ftdev.o |
31 | obj-$(CONFIG_SCHED_TASK_TRACE) += sched_task_trace.o | 32 | obj-$(CONFIG_SCHED_TASK_TRACE) += sched_task_trace.o |
diff --git a/litmus/pgm.c b/litmus/pgm.c new file mode 100644 index 000000000000..f8b857de8118 --- /dev/null +++ b/litmus/pgm.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* litmus/pgm.c - common pgm control code | ||
2 | */ | ||
3 | |||
4 | #include <linux/sched.h> | ||
5 | #include <litmus/litmus.h> | ||
6 | #include <litmus/pgm.h> | ||
7 | |||
8 | /* Only readjust release/deadline if difference is over a given threshold. | ||
9 | It's a weak method for accounting overheads. Ideally, we'd know the last | ||
10 | time t was woken up by its last predecessor, rather than having to look | ||
11 | at 'now'. */ | ||
12 | #define ADJUSTMENT_THRESH_US 200 | ||
13 | |||
14 | void setup_pgm_release(struct task_struct* t) | ||
15 | { | ||
16 | /* approximate time last predecessor gave us tokens */ | ||
17 | lt_t now = litmus_clock(); | ||
18 | |||
19 | TRACE_TASK(t, "is starting a new PGM job: waiting:%d satisfied:%d\n", | ||
20 | tsk_rt(t)->ctrl_page->pgm_waiting, tsk_rt(t)->ctrl_page->pgm_satisfied); | ||
21 | |||
22 | BUG_ON(!tsk_rt(t)->ctrl_page->pgm_waiting || !tsk_rt(t)->ctrl_page->pgm_satisfied); | ||
23 | |||
24 | tsk_rt(t)->ctrl_page->pgm_waiting = 0; | ||
25 | tsk_rt(t)->ctrl_page->pgm_satisfied = 0; | ||
26 | |||
27 | /* Adjust release time if we got the last tokens after release of this job. | ||
28 | This is possible since PGM jobs are early-released. Don't shift our | ||
29 | deadline if we got the tokens earlier than expected. */ | ||
30 | if (now > tsk_rt(t)->job_params.release) { | ||
31 | long long diff = now - tsk_rt(t)->job_params.release; | ||
32 | if (diff > ADJUSTMENT_THRESH_US) { | ||
33 | lt_t adj_deadline = now + get_rt_relative_deadline(t); | ||
34 | |||
35 | TRACE_TASK(t, "adjusting PGM release time from (r = %llu, d = %llu) " | ||
36 | "to (r = %llu, d = %llu)\n", | ||
37 | tsk_rt(t)->job_params.release, tsk_rt(t)->job_params.deadline, | ||
38 | now, adj_deadline); | ||
39 | |||
40 | tsk_rt(t)->job_params.release = now; | ||
41 | tsk_rt(t)->job_params.deadline = adj_deadline; | ||
42 | tsk_rt(t)->job_params.exec_time = 0; /* reset budget */ | ||
43 | } | ||
44 | else { | ||
45 | TRACE_TASK(t, "adjustment falls below threshold. %lld < %lld\n", | ||
46 | diff, ADJUSTMENT_THRESH_US); | ||
47 | } | ||
48 | } | ||
49 | else { | ||
50 | TRACE_TASK(t, "got tokens early--no need to adjust release. " | ||
51 | "cur time = %llu, release time = %llu\n", | ||
52 | now, tsk_rt(t)->job_params.release); | ||
53 | } | ||
54 | } | ||