Allow specifying interval value divisor from command line
[apc.git] / hog.c
blobe2a821d5c753575c0e53cc741228544d877e47c8
1 /* cc -o hog hog.c */
2 #define _POSIX_PTHREAD_SEMANTICS
3 #include <time.h>
4 #include <stdio.h>
5 #include <errno.h>
6 #include <stdarg.h>
7 #include <string.h>
8 #include <limits.h>
9 #include <stdlib.h>
10 #include <signal.h>
11 #include <sys/time.h>
13 #define HIST 10
15 static volatile sig_atomic_t stop;
17 static void sighandler (int signr)
19 (void) signr;
20 stop = 1;
23 static unsigned long hog (unsigned long niters)
25 stop = 0;
26 while (!stop && --niters)
28 return niters;
31 static void err (int status, const char *fmt, ...)
33 va_list ap;
34 int errno_code = errno;
36 va_start (ap, fmt);
37 vfprintf (stderr, fmt, ap);
38 va_end (ap);
39 fprintf (stderr, ": %s\n", strerror (errno_code));
40 exit (status);
43 int main (int argc, char **argv)
45 unsigned int i;
46 struct itimerval it;
47 struct sigaction act;
48 sigset_t set;
49 unsigned long v[HIST];
50 double tmp = 0.0;
51 unsigned long n;
52 long divisor;
54 if (argc > 1) {
55 char *endptr;
57 errno = 0;
58 divisor = strtol (argv[1], &endptr, 0);
59 if ((endptr && !*endptr)
60 || (errno == ERANGE && (divisor == LONG_MAX || divisor == LONG_MIN))
61 || (errno && divisor == 0)) {
62 err (EXIT_FAILURE, "Can't read `%s' as integer", argv[1]);
65 else {
66 divisor = 250;
69 act.sa_handler = sighandler;
70 if (sigemptyset (&act.sa_mask)) {
71 err (EXIT_FAILURE, "sigemptyset failed");
73 act.sa_flags = 0;
75 it.it_interval.tv_sec = 0;
76 it.it_interval.tv_usec = 1000000 / divisor;
77 it.it_value.tv_sec = 0;
78 it.it_value.tv_usec = 1000000 / divisor;
80 if (sigaction (SIGALRM, &act, NULL)) {
81 err (EXIT_FAILURE, "sigaction failed");
84 if (setitimer (ITIMER_REAL, &it, NULL)) {
85 err (EXIT_FAILURE, "setitimer failed");
88 hog (ULONG_MAX);
89 for (i = 0; i < HIST; ++i) {
90 v[i] = ULONG_MAX - hog (ULONG_MAX);
93 for (i = 0; i < HIST; ++i) {
94 printf ("%d = %ld\n", i, v[i]);
95 tmp += v[i];
97 tmp /= HIST;
98 n = tmp - (tmp / 3);
100 if (sigemptyset (&set)) {
101 err (EXIT_FAILURE, "sigemptyset failed");
104 if (sigaddset (&set, SIGALRM)) {
105 err (EXIT_FAILURE, "sigaddset failed");
108 for (;;) {
109 int signr;
111 hog (n);
112 if (sigwait (&set, &signr)) {
113 err (EXIT_FAILURE, "sigwait failed");