sys/arch/x86/include updates
[minix.git] / test / test41.c
blob314a404e7dddb999fe867638f6e01dc7e7941ca3
1 /* Tests for getitimer(2)/setitimer(2) - by D.C. van Moolenbroek */
2 /* Warning: this test deals with (real and virtual) time, and, lacking a proper
3 * point of reference, its correctness depends on circumstances like CPU speed
4 * and system load. A succeeding test run says a lot - failure not so much. */
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <time.h>
9 #include <minix/config.h>
10 #include <sys/types.h>
11 #include <sys/time.h>
12 #include <sys/wait.h>
13 #include <signal.h>
14 #include <unistd.h>
15 #include <errno.h>
17 #define ITERATIONS 3
18 #define MAX_ERROR 4
20 #include "common.c"
22 /* we have to keep in mind the millisecond values are rounded up */
23 #define UPPERUSEC(us) ((us)+(1000000/system_hz))
24 #define EQUSEC(l,r) \
25 ((l) <= ((r) + (1000000/system_hz)) && (l) >= ((r) - (1000000/system_hz)))
27 #define FILLITIMER(it, vs, vu, is, iu) \
28 (it).it_value.tv_sec = (vs); \
29 (it).it_value.tv_usec = (vu); \
30 (it).it_interval.tv_sec = (is); \
31 (it).it_interval.tv_usec = (iu);
33 /* these two macros are not fully working for all possible values;
34 * the tests only use values that the macros can deal with, though. */
35 #define EQITIMER(it, vs, vu, is, iu) \
36 ((it).it_value.tv_sec == (vs) && EQUSEC((it).it_value.tv_usec,vu) && \
37 (it).it_interval.tv_sec == (is) && (it).it_interval.tv_usec == (iu))
39 #define LEITIMER(it, vs, vu, is, iu) \
40 ((it).it_value.tv_sec > 0 && ((it).it_value.tv_sec < (vs) || \
41 ((it).it_value.tv_sec == (vs) && (it).it_value.tv_usec <= \
42 UPPERUSEC(vu))) && \
43 (it).it_interval.tv_sec == (is) && EQUSEC((it).it_interval.tv_usec,iu))
45 int main(int argc, char **argv);
46 void test(int m, int t);
47 void test_which(void);
48 void test_getset(void);
49 void test_neglarge(void);
50 void test_zero(void);
51 void test_timer(void);
52 void test_alarm(void);
53 void test_fork(void);
54 void test_exec(void);
55 int do_check(void);
56 void got_alarm(int sig);
57 void busy_wait(int secs);
58 void my_e(int n);
60 static char *executable;
61 static int signals;
62 static int timer;
63 static long system_hz;
65 static int sigs[] = { SIGALRM, SIGVTALRM, SIGPROF };
66 static const char *names[] = { "REAL", "VIRTUAL", "PROF" };
68 int main(argc, argv)
69 int argc;
70 char **argv;
72 int i, m = 0xFFFF, n = 0xF;
73 char cp_cmd[NAME_MAX+10];
75 system_hz = sysconf(_SC_CLK_TCK);
77 if (strcmp(argv[0], "DO CHECK") == 0) {
78 timer = atoi(argv[1]);
80 exit(do_check());
83 executable = argv[0];
85 start(41);
87 snprintf(cp_cmd, sizeof(cp_cmd), "cp ../%s .", executable);
88 system(cp_cmd);
90 if (argc >= 2) m = atoi(argv[1]);
91 if (argc >= 3) n = atoi(argv[2]);
93 for (i = 0; i < ITERATIONS; i++) {
94 if (n & 1) test(m, ITIMER_REAL);
95 if (n & 2) test(m, ITIMER_VIRTUAL);
96 if (n & 4) test(m, ITIMER_PROF);
99 quit();
100 return(-1); /* impossible */
103 void test(m, t)
104 int m;
105 int t;
107 timer = t;
109 if (m & 0001) test_which();
110 if (m & 0002) test_getset();
111 if (m & 0004) test_neglarge();
112 if (m & 0010) test_zero();
113 if (m & 0020) test_timer();
114 if (m & 0040) test_alarm();
115 if (m & 0100) test_fork();
116 if (m & 0200) test_exec();
119 /* test invalid and unsupported 'which' values */
120 void test_which()
122 struct itimerval it;
124 subtest = 0;
126 errno = 0; if (!getitimer(-1, &it) || errno != EINVAL) my_e(1);
127 errno = 0; if ( getitimer(timer, &it) ) my_e(2);
128 errno = 0; if (!getitimer( 3, &it) || errno != EINVAL) my_e(3);
131 /* test if we get back what we set */
132 void test_getset()
134 struct itimerval it, oit;
136 subtest = 1;
138 /* no alarm should be set initially */
139 if (getitimer(timer, &it)) my_e(1);
140 if (!EQITIMER(it, 0, 0, 0, 0)) my_e(2);
142 if (setitimer(timer, &it, &oit)) my_e(3);
143 if (setitimer(timer, &oit, NULL)) my_e(4);
144 if (!EQITIMER(oit, 0, 0, 0, 0)) my_e(5);
146 FILLITIMER(it, 123, 0, 456, 0);
147 if (setitimer(timer, &it, NULL)) my_e(6);
149 FILLITIMER(it, 987, 0, 654, 0);
150 if (setitimer(timer, &it, &oit)) my_e(7);
151 if (!LEITIMER(oit, 123, 0, 456, 0)) my_e(8);
153 if (getitimer(timer, &oit)) my_e(9);
154 if (!LEITIMER(oit, 987, 0, 654, 0)) my_e(10);
156 FILLITIMER(it, 0, 0, 0, 0);
157 if (setitimer(timer, &it, &oit)) my_e(11);
158 if (!LEITIMER(oit, 987, 0, 654, 0)) my_e(12);
160 if (getitimer(timer, &oit)) my_e(13);
161 if (!EQITIMER(oit, 0, 0, 0, 0)) my_e(14);
164 /* test negative/large values */
165 void test_neglarge()
167 struct itimerval it;
169 subtest = 2;
171 FILLITIMER(it, 4, 0, 5, 0);
172 if (setitimer(timer, &it, NULL)) my_e(1);
174 FILLITIMER(it, 1000000000, 0, 0, 0);
175 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(2);
177 FILLITIMER(it, 0, 1000000, 0, 0);
178 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(3);
180 FILLITIMER(it, 0, 0, 0, 1000000);
181 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(4);
183 FILLITIMER(it, -1, 0, 0, 0);
184 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(5);
186 FILLITIMER(it, 0, -1, 0, 0);
187 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(6);
189 FILLITIMER(it, 0, 0, -1, 0);
190 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(7);
192 FILLITIMER(it, 0, 0, 0, -1);
193 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(8);
195 if (getitimer(timer, &it)) my_e(9);
196 if (!LEITIMER(it, 4, 0, 5, 0)) my_e(10);
199 /* setitimer with a zero timer has to set the interval to zero as well */
200 void test_zero()
202 struct itimerval it;
204 subtest = 3;
206 it.it_value.tv_sec = 0;
207 it.it_value.tv_usec = 0;
208 it.it_interval.tv_sec = 1;
209 it.it_interval.tv_usec = 1;
211 if (setitimer(timer, &it, NULL)) my_e(1);
212 if (getitimer(timer, &it)) my_e(2);
213 if (!EQITIMER(it, 0, 0, 0, 0)) my_e(3);
216 /* test actual timer functioning */
217 void test_timer()
219 struct itimerval it;
221 subtest = 4;
223 if (signal(sigs[timer], got_alarm) == SIG_ERR) my_e(1);
225 FILLITIMER(it, 0, 1, 0, 1);
227 if (setitimer(timer, &it, NULL)) my_e(2);
229 signals = 0;
230 busy_wait(1);
232 FILLITIMER(it, 0, 0, 0, 0);
233 if (setitimer(timer, &it, NULL)) my_e(3);
235 /* we don't know how many signals we'll actually get in practice,
236 * so these checks more or less cover the extremes of the acceptable */
237 if (signals < 2) my_e(4);
238 if (signals > system_hz * 2) my_e(5);
240 /* only for REAL timer can we check against the clock */
241 if (timer == ITIMER_REAL) {
242 FILLITIMER(it, 1, 0, 0, 0);
243 if (setitimer(timer, &it, NULL)) my_e(6);
245 signals = 0;
246 busy_wait(1);
248 FILLITIMER(it, 0, 0, 0, 0);
249 if (setitimer(timer, &it, NULL)) my_e(7);
251 if (signals != 1) my_e(8);
254 signals = 0;
255 busy_wait(1);
257 if (signals != 0) my_e(9);
260 /* test itimer/alarm interaction */
261 void test_alarm(void) {
262 struct itimerval it;
264 /* only applicable for ITIMER_REAL */
265 if (timer != ITIMER_REAL) return;
267 subtest = 5;
269 if (signal(SIGALRM, got_alarm) == SIG_ERR) my_e(1);
271 FILLITIMER(it, 3, 0, 1, 0);
272 if (setitimer(timer, &it, NULL)) my_e(2);
274 if (alarm(2) != 3) my_e(3);
276 if (getitimer(timer, &it)) my_e(4);
277 if (!LEITIMER(it, 2, 0, 0, 0)) my_e(5);
279 signals = 0;
280 busy_wait(5);
282 if (signals != 1) my_e(6);
284 if (getitimer(timer, &it)) my_e(7);
285 if (!EQITIMER(it, 0, 0, 0, 0)) my_e(8);
288 /* test that the timer is reset on forking */
289 void test_fork(void) {
290 struct itimerval it, oit;
291 pid_t pid;
292 int status;
294 subtest = 6;
296 FILLITIMER(it, 12, 34, 56, 78);
298 if (setitimer(timer, &it, NULL)) my_e(1);
300 pid = fork();
301 if (pid < 0) my_e(2);
303 if (pid == 0) {
304 if (getitimer(timer, &it)) exit(5);
305 if (!EQITIMER(it, 0, 0, 0, 0)) exit(6);
307 exit(0);
310 if (wait(&status) != pid) my_e(3);
311 if (!WIFEXITED(status)) my_e(4);
312 if (WEXITSTATUS(status) != 0) my_e(WEXITSTATUS(status));
314 FILLITIMER(it, 0, 0, 0, 0);
315 if (setitimer(timer, &it, &oit)) my_e(7);
316 if (!LEITIMER(oit, 12, 34, 56, 78)) my_e(8);
319 /* test if timer is carried over to exec()'ed process */
320 void test_exec(void) {
321 struct itimerval it;
322 pid_t pid;
323 int status;
324 char buf[2];
326 subtest = 7;
328 pid = fork();
329 if (pid < 0) my_e(1);
331 if (pid == 0) {
332 FILLITIMER(it, 3, 0, 1, 0);
333 if (setitimer(timer, &it, NULL)) exit(2);
335 sprintf(buf, "%d", timer);
336 execl(executable, "DO CHECK", buf, NULL);
338 exit(3);
341 if (wait(&status) != pid) my_e(4);
342 if (WIFSIGNALED(status)) {
343 /* process should have died from corresponding signal */
344 if (WTERMSIG(status) != sigs[timer]) my_e(5);
346 else {
347 if (WIFEXITED(status)) my_e(WEXITSTATUS(status));
348 else my_e(6);
352 /* procedure of the exec()'ed process */
353 int do_check()
355 struct itimerval it;
357 if (getitimer(timer, &it)) return(81);
358 if (!LEITIMER(it, 3, 0, 1, 0)) return(82);
360 busy_wait(60);
362 return(83);
365 void busy_wait(secs)
366 int secs;
368 time_t now, exp;
369 int i;
371 exp = time(&now) + secs + 1;
373 while (now < exp) {
374 for (i = 0; i < 100000; i++);
376 time(&now);
380 void got_alarm(sig)
381 int sig;
383 if (sig != sigs[timer]) my_e(1001);
385 signals++;
388 void my_e(n)
389 int n;
392 printf("Timer %s, ", names[timer]);
393 e(n);