use oxpcie only if enabled to avoid baud bottleneck of uart.
[minix.git] / test / test41.c
blob2a0bc10649e009ead13096d0252b5a9525789054
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 <minix/sysinfo.h>
11 #include <sys/types.h>
12 #include <sys/time.h>
13 #include <sys/wait.h>
14 #include <signal.h>
15 #include <unistd.h>
16 #include <errno.h>
18 #define ITERATIONS 3
19 #define MAX_ERROR 4
21 /* we have to keep in mind the millisecond values are rounded up */
22 #define UPPERUSEC(us) ((us)+(1000000/system_hz))
23 #define EQUSEC(l,r) \
24 ((l) <= ((r) + (1000000/system_hz)) && (l) >= ((r) - (1000000/system_hz)))
26 #define FILLITIMER(it, vs, vu, is, iu) \
27 (it).it_value.tv_sec = (vs); \
28 (it).it_value.tv_usec = (vu); \
29 (it).it_interval.tv_sec = (is); \
30 (it).it_interval.tv_usec = (iu);
32 /* these two macros are not fully working for all possible values;
33 * the tests only use values that the macros can deal with, though. */
34 #define EQITIMER(it, vs, vu, is, iu) \
35 ((it).it_value.tv_sec == (vs) && EQUSEC((it).it_value.tv_usec,vu) && \
36 (it).it_interval.tv_sec == (is) && (it).it_interval.tv_usec == (iu))
38 #define LEITIMER(it, vs, vu, is, iu) \
39 ((it).it_value.tv_sec > 0 && ((it).it_value.tv_sec < (vs) || \
40 ((it).it_value.tv_sec == (vs) && (it).it_value.tv_usec <= \
41 UPPERUSEC(vu))) && \
42 (it).it_interval.tv_sec == (is) && EQUSEC((it).it_interval.tv_usec,iu))
44 _PROTOTYPE(int main, (int argc, char **argv));
45 _PROTOTYPE(void test, (int m, int t));
46 _PROTOTYPE(void test_which, (void));
47 _PROTOTYPE(void test_getset, (void));
48 _PROTOTYPE(void test_neglarge, (void));
49 _PROTOTYPE(void test_zero, (void));
50 _PROTOTYPE(void test_timer, (void));
51 _PROTOTYPE(void test_alarm, (void));
52 _PROTOTYPE(void test_fork, (void));
53 _PROTOTYPE(void test_exec, (void));
54 _PROTOTYPE(int do_check, (void));
55 _PROTOTYPE(void got_alarm, (int sig));
56 _PROTOTYPE(void busy_wait, (int secs));
57 _PROTOTYPE(void e, (int n));
58 _PROTOTYPE(void quit, (void));
60 static char *executable;
61 static int signals;
62 static int timer;
63 static int errct = 0, subtest;
64 static long system_hz;
66 static int sigs[] = { SIGALRM, SIGVTALRM, SIGPROF };
67 static const char *names[] = { "REAL", "VIRTUAL", "PROF" };
69 int main(argc, argv)
70 int argc;
71 char **argv;
73 int i, m = 0xFFFF, n = 0xF;
75 getsysinfo_up(PM_PROC_NR, SIU_SYSTEMHZ, sizeof(system_hz), &system_hz);
77 if (strcmp(argv[0], "DO CHECK") == 0) {
78 timer = atoi(argv[1]);
80 exit(do_check());
83 printf("Test 41 ");
84 fflush(stdout);
86 executable = argv[0];
88 if (argc >= 2) m = atoi(argv[1]);
89 if (argc >= 3) n = atoi(argv[2]);
91 for (i = 0; i < ITERATIONS; i++) {
92 if (n & 1) test(m, ITIMER_REAL);
93 if (n & 2) test(m, ITIMER_VIRTUAL);
94 if (n & 4) test(m, ITIMER_PROF);
97 quit();
98 return(-1); /* impossible */
101 void test(m, t)
102 int m;
103 int t;
105 timer = t;
107 if (m & 0001) test_which();
108 if (m & 0002) test_getset();
109 if (m & 0004) test_neglarge();
110 if (m & 0010) test_zero();
111 if (m & 0020) test_timer();
112 if (m & 0040) test_alarm();
113 if (m & 0100) test_fork();
114 if (m & 0200) test_exec();
117 /* test invalid and unsupported 'which' values */
118 void test_which()
120 struct itimerval it;
122 subtest = 0;
124 errno = 0; if (!getitimer(-1, &it) || errno != EINVAL) e(1);
125 errno = 0; if ( getitimer(timer, &it) ) e(2);
126 errno = 0; if (!getitimer( 3, &it) || errno != EINVAL) e(3);
129 /* test if we get back what we set */
130 void test_getset()
132 struct itimerval it, oit;
134 subtest = 1;
136 /* no alarm should be set initially */
137 if (getitimer(timer, &it)) e(1);
138 if (!EQITIMER(it, 0, 0, 0, 0)) e(2);
140 if (setitimer(timer, &it, &oit)) e(3);
141 if (setitimer(timer, &oit, NULL)) e(4);
142 if (!EQITIMER(oit, 0, 0, 0, 0)) e(5);
144 FILLITIMER(it, 123, 0, 456, 0);
145 if (setitimer(timer, &it, NULL)) e(6);
147 FILLITIMER(it, 987, 0, 654, 0);
148 if (setitimer(timer, &it, &oit)) e(7);
149 if (!LEITIMER(oit, 123, 0, 456, 0)) e(8);
151 if (getitimer(timer, &oit)) e(9);
152 if (!LEITIMER(oit, 987, 0, 654, 0)) e(10);
154 FILLITIMER(it, 0, 0, 0, 0);
155 if (setitimer(timer, &it, &oit)) e(11);
156 if (!LEITIMER(oit, 987, 0, 654, 0)) e(12);
158 if (getitimer(timer, &oit)) e(13);
159 if (!EQITIMER(oit, 0, 0, 0, 0)) e(14);
162 /* test negative/large values */
163 void test_neglarge()
165 struct itimerval it;
167 subtest = 2;
169 FILLITIMER(it, 4, 0, 5, 0);
170 if (setitimer(timer, &it, NULL)) e(1);
172 FILLITIMER(it, 1000000000, 0, 0, 0);
173 if (!setitimer(timer, &it, NULL) || errno != EINVAL) e(2);
175 FILLITIMER(it, 0, 1000000, 0, 0);
176 if (!setitimer(timer, &it, NULL) || errno != EINVAL) e(3);
178 FILLITIMER(it, 0, 0, 0, 1000000);
179 if (!setitimer(timer, &it, NULL) || errno != EINVAL) e(4);
181 FILLITIMER(it, -1, 0, 0, 0);
182 if (!setitimer(timer, &it, NULL) || errno != EINVAL) e(5);
184 FILLITIMER(it, 0, -1, 0, 0);
185 if (!setitimer(timer, &it, NULL) || errno != EINVAL) e(6);
187 FILLITIMER(it, 0, 0, -1, 0);
188 if (!setitimer(timer, &it, NULL) || errno != EINVAL) e(7);
190 FILLITIMER(it, 0, 0, 0, -1);
191 if (!setitimer(timer, &it, NULL) || errno != EINVAL) e(8);
193 if (getitimer(timer, &it)) e(9);
194 if (!LEITIMER(it, 4, 0, 5, 0)) e(10);
197 /* setitimer with a zero timer has to set the interval to zero as well */
198 void test_zero()
200 struct itimerval it;
202 subtest = 3;
204 it.it_value.tv_sec = 0;
205 it.it_value.tv_usec = 0;
206 it.it_interval.tv_sec = 1;
207 it.it_interval.tv_usec = 1;
209 if (setitimer(timer, &it, NULL)) e(1);
210 if (getitimer(timer, &it)) e(2);
211 if (!EQITIMER(it, 0, 0, 0, 0)) e(3);
214 /* test actual timer functioning */
215 void test_timer()
217 struct itimerval it;
219 subtest = 4;
221 if (signal(sigs[timer], got_alarm) == SIG_ERR) e(1);
223 FILLITIMER(it, 0, 1, 0, 1);
225 if (setitimer(timer, &it, NULL)) e(2);
227 signals = 0;
228 busy_wait(1);
230 FILLITIMER(it, 0, 0, 0, 0);
231 if (setitimer(timer, &it, NULL)) e(3);
233 /* we don't know how many signals we'll actually get in practice,
234 * so these checks more or less cover the extremes of the acceptable */
235 if (signals < 2) e(4);
236 if (signals > system_hz * 2) e(5);
238 /* only for REAL timer can we check against the clock */
239 if (timer == ITIMER_REAL) {
240 FILLITIMER(it, 1, 0, 0, 0);
241 if (setitimer(timer, &it, NULL)) e(6);
243 signals = 0;
244 busy_wait(1);
246 FILLITIMER(it, 0, 0, 0, 0);
247 if (setitimer(timer, &it, NULL)) e(7);
249 if (signals != 1) e(8);
252 signals = 0;
253 busy_wait(1);
255 if (signals != 0) e(9);
258 /* test itimer/alarm interaction */
259 void test_alarm(void) {
260 struct itimerval it;
262 /* only applicable for ITIMER_REAL */
263 if (timer != ITIMER_REAL) return;
265 subtest = 5;
267 if (signal(SIGALRM, got_alarm) == SIG_ERR) e(1);
269 FILLITIMER(it, 3, 0, 1, 0);
270 if (setitimer(timer, &it, NULL)) e(2);
272 if (alarm(2) != 3) e(3);
274 if (getitimer(timer, &it)) e(4);
275 if (!LEITIMER(it, 2, 0, 0, 0)) e(5);
277 signals = 0;
278 busy_wait(5);
280 if (signals != 1) e(6);
282 if (getitimer(timer, &it)) e(7);
283 if (!EQITIMER(it, 0, 0, 0, 0)) e(8);
286 /* test that the timer is reset on forking */
287 void test_fork(void) {
288 struct itimerval it, oit;
289 pid_t pid;
290 int status;
292 subtest = 6;
294 FILLITIMER(it, 12, 34, 56, 78);
296 if (setitimer(timer, &it, NULL)) e(1);
298 pid = fork();
299 if (pid < 0) e(2);
301 if (pid == 0) {
302 if (getitimer(timer, &it)) exit(5);
303 if (!EQITIMER(it, 0, 0, 0, 0)) exit(6);
305 exit(0);
308 if (wait(&status) != pid) e(3);
309 if (!WIFEXITED(status)) e(4);
310 if (WEXITSTATUS(status) != 0) e(WEXITSTATUS(status));
312 FILLITIMER(it, 0, 0, 0, 0);
313 if (setitimer(timer, &it, &oit)) e(7);
314 if (!LEITIMER(oit, 12, 34, 56, 78)) e(8);
317 /* test if timer is carried over to exec()'ed process */
318 void test_exec(void) {
319 struct itimerval it;
320 pid_t pid;
321 int status;
322 char buf[2];
324 subtest = 7;
326 pid = fork();
327 if (pid < 0) e(1);
329 if (pid == 0) {
330 FILLITIMER(it, 3, 0, 1, 0);
331 if (setitimer(timer, &it, NULL)) exit(2);
333 sprintf(buf, "%d", timer);
334 execl(executable, "DO CHECK", buf, NULL);
336 exit(3);
339 if (wait(&status) != pid) e(4);
340 if (WIFSIGNALED(status)) {
341 /* process should have died from corresponding signal */
342 if (WTERMSIG(status) != sigs[timer]) e(5);
344 else {
345 if (WIFEXITED(status)) e(WEXITSTATUS(status));
346 else e(6);
350 /* procedure of the exec()'ed process */
351 int do_check()
353 struct itimerval it;
355 if (getitimer(timer, &it)) return(81);
356 if (!LEITIMER(it, 3, 0, 1, 0)) return(82);
358 busy_wait(60);
360 return(83);
363 void busy_wait(secs)
364 int secs;
366 time_t now, exp;
367 int i;
369 exp = time(&now) + secs + 1;
371 while (now < exp) {
372 for (i = 0; i < 100000; i++);
374 time(&now);
378 void got_alarm(sig)
379 int sig;
381 if (sig != sigs[timer]) e(1001);
383 signals++;
386 void e(n)
387 int n;
390 printf("Timer %s, subtest %d, error %d, errno %d: %s\n",
391 names[timer], subtest, n, errno, strerror(errno));
393 if (errct++ > MAX_ERROR) {
394 printf("Too many errors; test aborted\n");
395 exit(1);
399 void quit()
402 if (errct == 0) {
403 printf("ok\n");
404 exit(0);
405 } else {
406 printf("%d errors\n", errct);
407 exit(1);