Remove building with NOCRYPTO option
[minix.git] / minix / tests / test41.c
blobee5ba6da47319e9baadc4977a0804702f60fe276
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 <sys/syslimits.h>
14 #include <signal.h>
15 #include <unistd.h>
16 #include <errno.h>
18 #define ITERATIONS 3
19 int max_error = 4;
20 #include "common.h"
24 /* we have to keep in mind the millisecond values are rounded up */
25 #define UPPERUSEC(us) ((us)+(1000000/system_hz))
26 #define EQUSEC(l,r) \
27 ((l) <= ((r) + (1000000/system_hz)) && (l) >= ((r) - (1000000/system_hz)))
29 #define FILLITIMER(it, vs, vu, is, iu) \
30 (it).it_value.tv_sec = (vs); \
31 (it).it_value.tv_usec = (vu); \
32 (it).it_interval.tv_sec = (is); \
33 (it).it_interval.tv_usec = (iu);
35 /* these two macros are not fully working for all possible values;
36 * the tests only use values that the macros can deal with, though. */
37 #define EQITIMER(it, vs, vu, is, iu) \
38 ((it).it_value.tv_sec == (vs) && EQUSEC((it).it_value.tv_usec,vu) && \
39 (it).it_interval.tv_sec == (is) && (it).it_interval.tv_usec == (iu))
41 #define LEITIMER(it, vs, vu, is, iu) \
42 ((it).it_value.tv_sec > 0 && ((it).it_value.tv_sec < (vs) || \
43 ((it).it_value.tv_sec == (vs) && (it).it_value.tv_usec <= \
44 UPPERUSEC(vu))) && \
45 (it).it_interval.tv_sec == (is) && EQUSEC((it).it_interval.tv_usec,iu))
47 int main(int argc, char **argv);
48 void test(int m, int t);
49 void test_which(void);
50 void test_getset(void);
51 void test_neglarge(void);
52 void test_zero(void);
53 void test_timer(void);
54 void test_alarm(void);
55 void test_fork(void);
56 void test_exec(void);
57 int do_check(void);
58 void got_alarm(int sig);
59 void busy_wait(int secs);
60 #define my_e(n) do { printf("Timer %s, ", names[timer]); e(n); } while(0)
62 static char *executable;
63 static int signals;
64 static int timer;
65 static long system_hz;
67 static int sigs[] = { SIGALRM, SIGVTALRM, SIGPROF };
68 static const char *names[] = { "REAL", "VIRTUAL", "PROF" };
70 int main(argc, argv)
71 int argc;
72 char **argv;
74 int i, m = 0xFFFF, n = 0xF;
75 char cp_cmd[NAME_MAX+10];
77 system_hz = sysconf(_SC_CLK_TCK);
79 if (strcmp(argv[0], "DO CHECK") == 0) {
80 timer = atoi(argv[1]);
82 exit(do_check());
85 executable = argv[0];
87 start(41);
89 snprintf(cp_cmd, sizeof(cp_cmd), "cp ../%s .", executable);
90 system(cp_cmd);
92 if (argc >= 2) m = atoi(argv[1]);
93 if (argc >= 3) n = atoi(argv[2]);
95 for (i = 0; i < ITERATIONS; i++) {
96 if (n & 1) test(m, ITIMER_REAL);
97 if (n & 2) test(m, ITIMER_VIRTUAL);
98 if (n & 4) test(m, ITIMER_PROF);
101 quit();
102 return(-1); /* impossible */
105 void test(m, t)
106 int m;
107 int t;
109 timer = t;
111 if (m & 0001) test_which();
112 if (m & 0002) test_getset();
113 if (m & 0004) test_neglarge();
114 if (m & 0010) test_zero();
115 if (m & 0020) test_timer();
116 if (m & 0040) test_alarm();
117 if (m & 0100) test_fork();
118 if (m & 0200) test_exec();
121 /* test invalid and unsupported 'which' values */
122 void test_which()
124 struct itimerval it;
126 subtest = 0;
128 errno = 0; if (!getitimer(-1, &it) || errno != EINVAL) my_e(1);
129 errno = 0; if ( getitimer(timer, &it) ) my_e(2);
130 errno = 0; if (!getitimer( 3, &it) || errno != EINVAL) my_e(3);
133 /* test if we get back what we set */
134 void test_getset()
136 struct itimerval it, oit;
138 subtest = 1;
140 /* no alarm should be set initially */
141 if (getitimer(timer, &it)) my_e(1);
142 if (!EQITIMER(it, 0, 0, 0, 0)) my_e(2);
144 if (setitimer(timer, &it, &oit)) my_e(3);
145 if (setitimer(timer, &oit, NULL)) my_e(4);
146 if (!EQITIMER(oit, 0, 0, 0, 0)) my_e(5);
148 FILLITIMER(it, 123, 0, 456, 0);
149 if (setitimer(timer, &it, NULL)) my_e(6);
151 FILLITIMER(it, 987, 0, 654, 0);
152 if (setitimer(timer, &it, &oit)) my_e(7);
153 if (!LEITIMER(oit, 123, 0, 456, 0)) my_e(8);
155 if (getitimer(timer, &oit)) my_e(9);
156 if (!LEITIMER(oit, 987, 0, 654, 0)) my_e(10);
158 FILLITIMER(it, 0, 0, 0, 0);
159 if (setitimer(timer, &it, &oit)) my_e(11);
160 if (!LEITIMER(oit, 987, 0, 654, 0)) my_e(12);
162 if (getitimer(timer, &oit)) my_e(13);
163 if (!EQITIMER(oit, 0, 0, 0, 0)) my_e(14);
166 /* test negative/large values */
167 void test_neglarge()
169 struct itimerval it;
171 subtest = 2;
173 FILLITIMER(it, 4, 0, 5, 0);
174 if (setitimer(timer, &it, NULL)) my_e(1);
176 FILLITIMER(it, 1000000000, 0, 0, 0);
177 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(2);
179 FILLITIMER(it, 0, 1000000, 0, 0);
180 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(3);
182 FILLITIMER(it, 0, 0, 0, 1000000);
183 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(4);
185 FILLITIMER(it, -1, 0, 0, 0);
186 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(5);
188 FILLITIMER(it, 0, -1, 0, 0);
189 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(6);
191 FILLITIMER(it, 0, 0, -1, 0);
192 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(7);
194 FILLITIMER(it, 0, 0, 0, -1);
195 if (!setitimer(timer, &it, NULL) || errno != EINVAL) my_e(8);
197 if (getitimer(timer, &it)) my_e(9);
198 if (!LEITIMER(it, 4, 0, 5, 0)) my_e(10);
201 /* setitimer with a zero timer has to set the interval to zero as well */
202 void test_zero()
204 struct itimerval it;
206 subtest = 3;
208 it.it_value.tv_sec = 0;
209 it.it_value.tv_usec = 0;
210 it.it_interval.tv_sec = 1;
211 it.it_interval.tv_usec = 1;
213 if (setitimer(timer, &it, NULL)) my_e(1);
214 if (getitimer(timer, &it)) my_e(2);
215 if (!EQITIMER(it, 0, 0, 0, 0)) my_e(3);
218 /* test actual timer functioning */
219 void test_timer()
221 struct itimerval it;
223 subtest = 4;
225 if (signal(sigs[timer], got_alarm) == SIG_ERR) my_e(1);
227 FILLITIMER(it, 0, 100000, 0, 100000);
229 if (setitimer(timer, &it, NULL)) my_e(2);
231 signals = 0;
232 busy_wait(1);
234 FILLITIMER(it, 0, 0, 0, 0);
235 if (setitimer(timer, &it, NULL)) my_e(3);
237 /* we don't know how many signals we'll actually get in practice,
238 * so these checks more or less cover the extremes of the acceptable */
239 if (signals < 2) my_e(4);
240 if (signals > system_hz * 2) my_e(5);
242 /* only for REAL timer can we check against the clock */
243 if (timer == ITIMER_REAL) {
244 FILLITIMER(it, 1, 0, 0, 0);
245 if (setitimer(timer, &it, NULL)) my_e(6);
247 signals = 0;
248 busy_wait(1);
250 FILLITIMER(it, 0, 0, 0, 0);
251 if (setitimer(timer, &it, NULL)) my_e(7);
253 if (signals != 1) my_e(8);
256 signals = 0;
257 busy_wait(1);
259 if (signals != 0) my_e(9);
262 /* test itimer/alarm interaction */
263 void test_alarm(void) {
264 struct itimerval it;
266 /* only applicable for ITIMER_REAL */
267 if (timer != ITIMER_REAL) return;
269 subtest = 5;
271 if (signal(SIGALRM, got_alarm) == SIG_ERR) my_e(1);
273 FILLITIMER(it, 3, 0, 1, 0);
274 if (setitimer(timer, &it, NULL)) my_e(2);
276 if (alarm(2) != 3) my_e(3);
278 if (getitimer(timer, &it)) my_e(4);
279 if (!LEITIMER(it, 2, 0, 0, 0)) my_e(5);
281 signals = 0;
282 busy_wait(5);
284 if (signals != 1) my_e(6);
286 if (getitimer(timer, &it)) my_e(7);
287 if (!EQITIMER(it, 0, 0, 0, 0)) my_e(8);
290 /* test that the timer is reset on forking */
291 void test_fork(void) {
292 struct itimerval it, oit;
293 pid_t pid;
294 int status;
296 subtest = 6;
298 FILLITIMER(it, 12, 34, 56, 78);
300 if (setitimer(timer, &it, NULL)) my_e(1);
302 pid = fork();
303 if (pid < 0) my_e(2);
305 if (pid == 0) {
306 if (getitimer(timer, &it)) exit(5);
307 if (!EQITIMER(it, 0, 0, 0, 0)) exit(6);
309 exit(0);
312 if (wait(&status) != pid) my_e(3);
313 if (!WIFEXITED(status)) my_e(4);
314 if (WEXITSTATUS(status) != 0) my_e(WEXITSTATUS(status));
316 FILLITIMER(it, 0, 0, 0, 0);
317 if (setitimer(timer, &it, &oit)) my_e(7);
318 if (!LEITIMER(oit, 12, 34, 56, 78)) my_e(8);
321 /* test if timer is carried over to exec()'ed process */
322 void test_exec(void) {
323 struct itimerval it;
324 pid_t pid;
325 int status;
326 char buf[2];
328 subtest = 7;
330 pid = fork();
331 if (pid < 0) my_e(1);
333 if (pid == 0) {
334 FILLITIMER(it, 3, 0, 1, 0);
335 if (setitimer(timer, &it, NULL)) exit(2);
337 sprintf(buf, "%d", timer);
338 execl(executable, "DO CHECK", buf, NULL);
340 exit(3);
343 if (wait(&status) != pid) my_e(4);
344 if (WIFSIGNALED(status)) {
345 /* process should have died from corresponding signal */
346 if (WTERMSIG(status) != sigs[timer]) my_e(5);
348 else {
349 if (WIFEXITED(status)) my_e(WEXITSTATUS(status));
350 else my_e(6);
354 /* procedure of the exec()'ed process */
355 int do_check()
357 struct itimerval it;
359 if (getitimer(timer, &it)) return(81);
360 if (!LEITIMER(it, 3, 0, 1, 0)) return(82);
362 busy_wait(60);
364 return(83);
367 void busy_wait(secs)
368 int secs;
370 time_t now, exp;
371 int i;
373 exp = time(&now) + secs + 1;
375 while (now < exp) {
376 for (i = 0; i < 100000; i++);
378 time(&now);
382 void got_alarm(sig)
383 int sig;
385 if (sig != sigs[timer]) my_e(1001);
387 signals++;