xref: /openbsd/regress/sys/kern/itimer/itimer.c (revision 771fbea0)
1 /*	$OpenBSD: itimer.c,v 1.2 2013/09/12 23:06:44 krw Exp $	*/
2 /*
3  *	Written by Artur Grabowski <art@openbsd.org> 2004 Public Domain.
4  */
5 #include <sys/types.h>
6 #include <sys/time.h>
7 #include <sys/resource.h>
8 
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <unistd.h>
12 #include <time.h>
13 #include <err.h>
14 #include <signal.h>
15 
16 void sighand(int);
17 
18 volatile sig_atomic_t ticks;
19 
20 #define TIMEOUT	2
21 
22 int
23 main(int argc, char **argv)
24 {
25 	struct timeval stv, tv;
26 	struct itimerval itv;
27 	struct rusage ru;
28 	int which, sig;
29 	int ch;
30 
31 	while ((ch = getopt(argc, argv, "rvp")) != -1) {
32 		switch (ch) {
33 		case 'r':
34 			which = ITIMER_REAL;
35 			sig = SIGALRM;
36 			break;
37 		case 'v':
38 			which = ITIMER_VIRTUAL;
39 			sig = SIGVTALRM;
40 			break;
41 		case 'p':
42 			which = ITIMER_PROF;
43 			sig = SIGPROF;
44 			break;
45 		default:
46 			fprintf(stderr, "Usage: itimer [-rvp]\n");
47 			exit(1);
48 		}
49 	}
50 
51 	signal(sig, sighand);
52 
53 	itv.it_value.tv_sec = 0;
54 	itv.it_value.tv_usec = 100000;
55 	itv.it_interval = itv.it_value;
56 
57 	if (setitimer(which, &itv, NULL) != 0)
58 		err(1, "setitimer");
59 
60 	gettimeofday(&stv, NULL);
61 	while (ticks != TIMEOUT * 10)
62 		;
63 
64 	switch (which) {
65 	case ITIMER_REAL:
66 		gettimeofday(&tv, NULL);
67 		timersub(&tv, &stv, &tv);
68 		break;
69 	case ITIMER_VIRTUAL:
70 	case ITIMER_PROF:
71 		if (getrusage(RUSAGE_SELF, &ru) != 0)
72 			err(1, "getrusage");
73 		tv = ru.ru_utime;
74 		break;
75 	}
76 	stv.tv_sec = TIMEOUT;
77 	stv.tv_usec = 0;
78 
79 	if (timercmp(&stv, &tv, <))
80 		timersub(&tv, &stv, &tv);
81 	else
82 		timersub(&stv, &tv, &tv);
83 
84 	if (tv.tv_sec != 0 || tv.tv_usec > 100000)
85 		errx(1, "timer difference too big: %lld.%ld",
86 		    (long long)tv.tv_sec, tv.tv_usec);
87 
88 	return (0);
89 }
90 
91 void
92 sighand(int signum)
93 {
94 	ticks++;
95 }
96