aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/pgm.c
blob: 0bc190851718a9572132003962b23a3cbeefe1d6 (plain) (blame)
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);
}