dahdi_cfg: error()->perror() when sem_open fails.
[dahdi/tools.git] / dahdi_test.c
1 /*
2  * Written by Mark Spencer <markster@digium.com>
3  * Based on previous works, designs, and architectures conceived and
4  * written by Jim Dixon <jim@lambdatel.com>.
5  *
6  * Copyright (C) 2001 Jim Dixon / Zapata Telephony.
7  * Copyright (C) 2001-2008 Digium, Inc.
8  *
9  * All rights reserved.
10  *
11  * Primary Author: Mark Spencer <markster@digium.com>
12  * Radio Support by Jim Dixon <jim@lambdatel.com>
13  */
14
15 /*
16  * See http://www.asterisk.org for more information about
17  * the Asterisk project. Please do not directly contact
18  * any of the maintainers of this project for assistance;
19  * the project provides a web site, mailing lists and IRC
20  * channels for your use.
21  *
22  * This program is free software, distributed under the terms of
23  * the GNU General Public License Version 2 as published by the
24  * Free Software Foundation. See the LICENSE file included with
25  * this program for more details.
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <errno.h>
32 #include <string.h>
33 #include <fcntl.h>
34 #include <sys/time.h>
35 #include <sys/signal.h>
36 #include <math.h>
37 #include <getopt.h>
38
39 #include "dahdi_tools_version.h"
40
41 #define SIZE 8000
42
43 static int verbose;
44 static int pass = 0;
45 static float best = 0.0;
46 static float worst = 100.0;
47 static double total = 0.0;
48 static double total_time = 0.0;
49 static double total_count = 0.0;
50
51 static inline float _fmin(float a, float b)
52 {
53         return (a < b) ? a : b;
54 }
55
56 static double calculate_accuracy(double count, double ms)
57 {
58         return ((count - _fmin(count, fabs(count - ms))) / count) * 100.0;
59 }
60
61 void hup_handler(int sig)
62 {
63         double accuracy = calculate_accuracy(total_count, total_time);
64         printf("\n--- Results after %d passes ---\n", pass);
65         printf("Best: %.3f%% -- Worst: %.3f%% -- Average: %f%%\n",
66                         best, worst, pass ? total/pass : 100.00);
67         printf("Cummulative Accuracy (not per pass): %0.3f\n",
68                pass ? accuracy : 0.0);
69         exit(0);
70 }
71
72 static void usage(char *argv0)
73 {
74         char *c;
75         c = strrchr(argv0, '/');
76         if (!c)
77                 c = argv0;
78         else
79                 c++;
80         fprintf(stderr, 
81                 "Usage: %s [-c COUNT] [-v]\n"
82                 "    Valid options are:\n"
83                 "  -c COUNT    Run just COUNT cycles (otherwise: forever).\n"
84                 "  -v          More verbose output.\n"
85                 "  -h          This help text.\n"
86         , c);
87 }
88
89 int main(int argc, char *argv[])
90 {
91         int fd;
92         int res;
93         int c;
94         int count = 0;
95         int seconds = 0;
96         int curarg = 1;
97         char buf[8192];
98         float ms;
99         struct timeval start, now;
100         fd = open("/dev/dahdi/pseudo", O_RDWR);
101         if (fd < 0) {
102                 fprintf(stderr, "Unable to open dahdi interface: %s\n", strerror(errno));
103                 exit(1);
104         }
105         
106         while ((c = getopt(argc, argv, "c:hv")) != -1) {
107                 switch(c) {
108                 case 'c':
109                         seconds = atoi(optarg);
110                         break;
111                 case 'h':
112                         usage(argv[0]);
113                         exit(0);
114                         break;
115                 case '?':
116                         usage(argv[0]);
117                         exit(1);
118                         break;
119                 case 'v':
120                         verbose++;
121                         break;
122                 }
123         }
124         while (curarg < argc) {
125                 if (!strcasecmp(argv[curarg], "-v"))
126                         verbose++;
127                 if (!strcasecmp(argv[curarg], "-c") && argc > curarg)
128                         seconds = atoi(argv[curarg + 1]);
129                 curarg++;
130         }
131         printf("Opened pseudo dahdi interface, measuring accuracy...\n");
132         signal(SIGHUP, hup_handler);
133         signal(SIGINT, hup_handler);
134         signal(SIGALRM, hup_handler);
135         /* Flush input buffer */
136         for (count = 0; count < 4; count++)
137                 res = read(fd, buf, sizeof(buf));
138         count = 0;
139         ms = 0; /* Makes the compiler happy */
140         if (seconds > 0)
141                 alarm(seconds + 1); /* This will give 'seconds' cycles */
142         for (;;) {
143                 if (count == 0)
144                         ms = 0;
145                 gettimeofday(&start, NULL);
146                 res = read(fd, buf, sizeof(buf));
147                 if (res < 0) {
148                         fprintf(stderr, "Failed to read from pseudo interface: %s\n", strerror(errno));
149                         exit(1);
150                 }
151                 count += res;
152                 gettimeofday(&now, NULL);
153                 ms += (now.tv_sec - start.tv_sec) * 8000;
154                 ms += (now.tv_usec - start.tv_usec) / 125.0;
155                 if (count >= SIZE) {
156                         const double percent = calculate_accuracy(count, ms);
157                         if (verbose) {
158                                 printf("\n%d samples in %0.3f system clock sample intervals (%.3f%%)", 
159                                                 count, ms, percent);
160                         } else if (pass > 0 && (pass % 8) == 0) {
161                                 printf("\n");
162                         }
163                         if (percent > best)
164                                 best = percent;
165                         if (percent < worst)
166                                 worst = percent;
167                         if (!verbose)
168                                 printf("%.3f%% ", percent);
169                         total += percent;
170                         fflush(stdout);
171                         total_count += count;
172                         total_time += ms;
173                         count = 0;
174                         pass++;
175                 }
176         }
177 }