1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
/* litmus/pgm.c - common pgm control code
*/
#include <linux/sched.h>
#include <litmus/litmus.h>
#include <litmus/pgm.h>
#include <litmus/sched_trace.h>
/* Only readjust release/deadline if difference is over a given threshold.
It's a weak method for accounting overheads. Ideally, we'd know the last
time t was woken up by its last predecessor, rather than having to look
at 'now'. Adjustment threshold currently set to 200us. */
#define ADJUSTMENT_THRESH_NS (200*1000LL)
void setup_pgm_release(struct task_struct* t)
{
/* approximate time last predecessor gave us tokens */
lt_t now = litmus_clock();
TRACE_TASK(t, "is starting a new PGM job: waiting:%d satisfied:%d\n",
tsk_rt(t)->ctrl_page->pgm_waiting, tsk_rt(t)->ctrl_page->pgm_satisfied);
BUG_ON(!tsk_rt(t)->ctrl_page->pgm_waiting || !tsk_rt(t)->ctrl_page->pgm_satisfied);
tsk_rt(t)->ctrl_page->pgm_waiting = 0;
tsk_rt(t)->ctrl_page->pgm_satisfied = 0;
/* Adjust release time if we got the last tokens after release of this job.
This is possible since PGM jobs are early-released. Don't shift our
deadline if we got the tokens earlier than expected. */
if (now > tsk_rt(t)->job_params.release) {
long long diff_ns = now - tsk_rt(t)->job_params.release;
if (diff_ns > ADJUSTMENT_THRESH_NS) {
lt_t adj_deadline = now + get_rt_relative_deadline(t);
TRACE_TASK(t, "adjusting PGM release time from (r = %llu, d = %llu) "
"to (r = %llu, d = %llu)\n",
tsk_rt(t)->job_params.release, tsk_rt(t)->job_params.deadline,
now, adj_deadline);
tsk_rt(t)->job_params.release = now;
tsk_rt(t)->job_params.deadline = adj_deadline;
tsk_rt(t)->job_params.exec_time = 0; /* reset budget */
}
else {
TRACE_TASK(t, "adjustment falls below threshold. %lld < %lld\n",
diff_ns, ADJUSTMENT_THRESH_NS);
}
}
else {
TRACE_TASK(t, "got tokens early--no need to adjust release. "
"cur time = %llu, release time = %llu\n",
now, tsk_rt(t)->job_params.release);
}
sched_trace_pgm_release(t);
}
|