Initial commit of simple (just forwarding from CAN0 to CAN1 and back) CAN gateway...
[can-benchmark.git] / utils / testlo.c
1 #include <fcntl.h>
2 #include <netinet/ip.h>
3 #include <stdio.h>
4 #include <sys/socket.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #include <time.h>
8 #include <unistd.h>
9
10 /* Subtract the `struct timespec' values X and Y,
11    storing the result in RESULT.
12    Return 1 if the difference is negative, otherwise 0.  */
13
14 int
15 timespec_subtract (result, x, y)
16 struct timespec *result, *x, *y;
17 {
18         /* Perform the carry for the later subtraction by updating Y. */
19         if (x->tv_nsec < y->tv_nsec) {
20                 int nsec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
21                 y->tv_nsec -= 1000000000 * nsec;
22                 y->tv_sec += nsec;
23         }
24         if (x->tv_nsec - y->tv_nsec > 1000000000) {
25                 int nsec = (x->tv_nsec - y->tv_nsec) / 1000000000;
26                 y->tv_nsec += 1000000000 * nsec;
27                 y->tv_sec -= nsec;
28         }
29
30         /* Compute the time remaining to wait.
31            `tv_nsec' is certainly positive. */
32         result->tv_sec = x->tv_sec - y->tv_sec;
33         result->tv_nsec = x->tv_nsec - y->tv_nsec;
34
35         /* Return 1 if result is negative. */
36         return x->tv_sec < y->tv_sec;
37 }
38
39 int slave(int srx)
40 {
41         int ret; 
42         char msgr[100];
43         struct sockaddr a;
44         socklen_t alen = sizeof(a);
45
46         while (1) {
47                 ret = recvfrom(srx, msgr, sizeof(msgr), 0, &a, &alen);
48                 if (ret == -1) perror("slave recvfrom");
49                 ret = sendto(srx, msgr, ret, 0, &a, alen);
50                 if (ret == -1) perror("slave sendto");
51         }
52 }
53
54
55 #define HIST_SIZE 1000
56 #define HIST_MAX_US 100000
57 unsigned hist[1000];
58
59 int usec2hist(int usec)
60 {
61         int i;
62         i = HIST_SIZE*usec/HIST_MAX_US;
63         if (i >= HIST_SIZE)
64                 i = HIST_SIZE;
65         hist[i]++;
66 }
67
68 int main()
69 {
70         int stx, srx;
71         struct sockaddr_in a;
72         struct timespec tstart, tend, t;
73         char msg[] = "asdf";
74         char msgr[100];
75         int ret;
76         int usec, max=0;
77         int i;
78         pid_t pid;
79         
80         stx = socket(PF_INET, SOCK_DGRAM, 0);
81         a.sin_family = AF_INET;
82         a.sin_port = htons(1234);
83         a.sin_addr.s_addr = inet_addr("127.1.2.3");
84         srx = socket(PF_INET, SOCK_DGRAM, 0);
85         bind(srx, (struct sockaddr*)&a, sizeof(a));
86
87         pid = fork();
88         if (pid < 0)
89                 perror("fork");
90         if (pid == 0) {
91                 slave(srx);
92                 return 0;
93         }
94         close(srx);
95
96         for (i=0; i<10000; i++) {
97                 clock_gettime(CLOCK_MONOTONIC, &tstart);
98                 ret = sendto(stx, msg, sizeof(msg), 0, (struct sockaddr*)&a, sizeof(a));
99                 if (ret == -1) perror("main sendto");
100                 ret = recv(stx, msgr, sizeof(msgr), 0);
101                 if (ret == -1) perror("main recv");
102                 clock_gettime(CLOCK_MONOTONIC, &tend);
103                 timespec_subtract(&t, &tend, &tstart);
104                 
105                 usec = t.tv_sec*1000000 + t.tv_nsec/1000;
106                 usec2hist(usec);
107                 if (usec > max) {
108                         max = usec;
109                         //printf("%d.%.03d\n", usec/1000, usec%1000);
110                 }
111                 
112         }
113
114         kill(pid);
115
116         printf("Duration: %d.%.03d ms\n", max/1000, max%1000);
117
118
119         /* Draw histogram */
120         int fd[2];
121         pipe(fd);
122         pid = fork();
123         if (pid < 0) {
124                 perror("fork gnuplot");
125                 return 1;
126         } else if(pid == 0)
127         {
128                 close(fd[1]);
129                 dup2(fd[0], 0);
130 /*              int n = open("/dev/null", O_RDWR); */
131 /*                 dup2(n, 1); */
132 /*                 dup2(n, 2); */
133                 execlp("gnuplot", "gnuplot", "-persist", NULL);
134         }
135         close(fd[0]);
136         FILE *f = fdopen(fd[1], "a");
137         fprintf(f, "set xlabel 'ms'\n");
138         fprintf(f, "set logscale y\n");
139         fprintf(f, "plot '-' with steps\n");
140         int j;
141         for (j=0; j<HIST_SIZE; j++) {
142                 if (hist[j]) {
143                         fprintf(f, "%g %d\n", j/10.0, i);
144                         i -= hist[j];
145                 }
146         }
147         fprintf(f, "e\n", i, hist[i]);
148         fflush(f);
149         fclose(f);
150         sleep(10);
151         wait(pid);
152         return 0;
153 }