perl version of histogram prog
[tridge/junkcode.git] / rshell_latency.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <sys/time.h>
6 #include <time.h>
7 #include <string.h>
8
9 static struct timeval tp1,tp2;
10
11 static void start_timer()
12 {
13         gettimeofday(&tp1,NULL);
14 }
15
16 static double end_timer()
17 {
18         gettimeofday(&tp2,NULL);
19         return (tp2.tv_sec + (tp2.tv_usec*1.0e-6)) - 
20                 (tp1.tv_sec + (tp1.tv_usec*1.0e-6));
21 }
22
23
24 static pid_t piped_child(const char *command[], int *f_in, int *f_out)
25 {
26         pid_t pid;
27         int to_child_pipe[2];
28         int from_child_pipe[2];
29
30         if (pipe(to_child_pipe) < 0 || pipe(from_child_pipe) < 0) {
31                 perror("pipe");
32                 exit(1);
33         }
34
35         pid = fork();
36         if (pid == -1) {
37                 perror("fork");
38                 exit(1);
39         }
40
41         if (pid == 0) {
42                 if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
43                     close(to_child_pipe[1]) < 0 ||
44                     close(from_child_pipe[0]) < 0 ||
45                     dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
46                         printf("Failed to dup/close");
47                         exit(1);
48                 }
49                 if (to_child_pipe[0] != 0)
50                         close(to_child_pipe[0]);
51                 if (from_child_pipe[1] != 1)
52                         close(from_child_pipe[1]);
53                 execvp(command[0], command);
54                 printf("Failed to exec %s", command[0]);
55                 exit(1);
56         }
57
58         if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
59                 printf("Failed to close");
60                 exit(1);
61         }
62
63         *f_in = from_child_pipe[0];
64         *f_out = to_child_pipe[1];
65
66         return pid;
67 }
68
69
70 int main(int argc, const char *argv[])
71 {
72         pid_t pid;
73         int fd_in, fd_out;
74         double max_latency=0.0, min_latency=0.0, total_latency=0.0;
75         unsigned num_calls = 0;
76         char buf[] = "testing0\n";
77         char buf2[10];
78         int len = strlen(buf);
79         int print_count=0;
80
81         pid = piped_child(argv+1, &fd_in, &fd_out);
82
83         /* ignore first round trip */
84         if (write(fd_out, buf, len) != len) {
85                 printf("write error\n");
86                 exit(1);
87         }
88         if (read(fd_in, buf2, len) != len) {
89                 printf("read error\n");
90                 exit(1);
91         }
92
93         while (1) {
94                 double lat;
95                 buf[len-2] = num_calls%10;
96                 start_timer();
97                 if (write(fd_out, buf, len) != len) {
98                         printf("write error\n");
99                         break;
100                 }
101                 if (read(fd_in, buf2, len) != len) {
102                         printf("read error\n");
103                         break;
104                 }
105                 lat = end_timer();
106                 if (memcmp(buf, buf2, len) != 0) {
107                         printf("Wrong data: %s\n", buf2);
108                 }
109                 if (lat < min_latency || min_latency == 0.0) {
110                         min_latency = lat;
111                 }
112                 if (lat > max_latency) {
113                         max_latency = lat;
114                 }
115                 total_latency += lat;
116                 num_calls++;
117                 if (total_latency > print_count+1) {
118                         print_count++;
119                         printf("Calls: %6u Latency: min=%.6f max=%.6f avg=%.6f\n",
120                                num_calls, 
121                                min_latency, max_latency, total_latency/num_calls);
122                         min_latency = 0;
123                         max_latency = 0;
124                         fflush(stdout);
125                 }
126         }
127
128         return 0;       
129 }