aboutsummaryrefslogtreecommitdiffstats
path: root/tests/sched.c
blob: 6726b46df18f9314456860577cad3428cdf870b7 (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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <sys/wait.h> /* for waitpid() */
#include <unistd.h>
#include <stdio.h>

#include "tests.h"
#include "litmus.h"

TESTCASE(preempt_on_resume, P_FP | PSN_EDF,
	 "preempt lower-priority task when a higher-priority task resumes")
{
	int child_hi, child_lo, status, waiters;
	lt_t delay = ms2ns(100);
	double start, stop;

	struct rt_task params;
	init_rt_task_param(&params);
	params.cpu        = 0;
	params.exec_cost  = ms2ns(10000);
	params.period     = ms2ns(100000);
	params.relative_deadline = params.period;
	params.phase      = 0;
	params.cls        = RT_CLASS_HARD;
	params.budget_policy = NO_ENFORCEMENT;

	child_lo = FORK_TASK(
		params.priority = LITMUS_LOWEST_PRIORITY;
		SYSCALL( set_rt_task_param(gettid(), &params) );
		SYSCALL( be_migrate_to_cpu(params.cpu) );
		SYSCALL( task_mode(LITMUS_RT_TASK) );

		SYSCALL( wait_for_ts_release() );

		start = cputime();

		while (cputime() - start < 10)
			;

		);

	child_hi = FORK_TASK(
		params.priority	= LITMUS_HIGHEST_PRIORITY;
		params.relative_deadline -= 1000000;
		SYSCALL( set_rt_task_param(gettid(), &params) );
		SYSCALL( be_migrate_to_cpu(params.cpu) );
		SYSCALL( task_mode(LITMUS_RT_TASK) );

		SYSCALL( wait_for_ts_release() );

		start = cputime();

		while (cputime() - start < 0.1)
			;

		start = wctime();
		SYSCALL( lt_sleep(ms2ns(100)) );
		stop = wctime();

		SYSCALL( kill(child_lo, SIGUSR2) );

		if (stop - start >= 0.2)
			fprintf(stderr, "\nHi-prio delay = %fsec\n",
				stop - start - (ms2ns(100) / (float)s2ns(1)));

		/* Assert we woke up 'soonish' after the sleep. */
		ASSERT( stop - start < 0.2 );
		);


	do {
		waiters = get_nr_ts_release_waiters();
		ASSERT( waiters >= 0 );
	} while (waiters != 2);

	waiters = release_ts(&delay);

	SYSCALL( waitpid(child_hi, &status, 0) );
	ASSERT( status == 0 );

	SYSCALL( waitpid(child_lo, &status, 0) );
	ASSERT( status ==  SIGUSR2);
}