Add a socketpair performance tester.
[dragonfly.git] / test / sysperf / socketpair.c
1 /*
2  * socketpair.c
3  *
4  * $DragonFly$
5  */
6
7 #include "blib.h"
8 #include <sys/resource.h>
9 #include <sys/socket.h>
10 #include <sys/un.h>
11
12 #define PAGE_SIZE       4096
13 #define PAGE_MASK       (PAGE_SIZE - 1)
14
15 int
16 main(int ac, char **av)
17 {
18     long long count = 0;
19     long long max;
20     char c;
21     int j;
22     int loops;
23     int bytes;
24     int ppri = 999;
25     int fds[2];
26     char *buf;
27     char *ptr;
28     char *msg = "datarate";
29
30     if (ac == 1) {
31         fprintf(stderr, "%s blocksize[k,m] [pipe_writer_pri] [msg]\n", av[0]);
32         exit(1);
33     }
34     bytes = strtol(av[1], &ptr, 0);
35     if (*ptr == 'k' || *ptr == 'K') {
36         bytes *= 1024;
37     } else if (*ptr == 'm' || *ptr == 'M') {
38         bytes *= 1024 * 1024;
39     } else if (*ptr) {
40         fprintf(stderr, "Illegal numerical suffix: %s\n", ptr);
41         exit(1);
42     }
43     if (bytes <= 0) {
44         fprintf(stderr, "I can't handle %d sized buffers\n", bytes);
45         exit(1);
46     }
47     if (ac >= 3)
48         ppri = strtol(av[2], NULL, 0);
49     if (ac >= 4)
50         msg = av[3];
51
52     buf = mmap(NULL, bytes * 2 + PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
53     if (buf == MAP_FAILED) {
54         perror("mmap/buffer");
55         exit(1);
56     }
57
58     bzero(buf, bytes * 2 + PAGE_SIZE);
59
60     printf("tests one-way socketpair\n");
61     if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, fds)) {
62         perror("socketpair");
63         exit(1);
64     }
65     if (fork() == 0) {
66         /*
67          * child process
68          */
69         int n;
70         int i;
71
72         close(fds[0]);
73         buf += (bytes + PAGE_MASK) & ~PAGE_MASK;
74         i = 0;
75         for (;;) {
76             n = read(fds[1], buf + i, bytes - i);
77             if (n <= 0)
78                 break;
79             if (n + i == bytes)
80                 i = 0;
81             else
82                 i += n;
83         }
84         _exit(0);
85     } else {
86         /*
87          * parent process.
88          */
89         if (ppri != 999) {
90             if (setpriority(PRIO_PROCESS, getpid(), ppri) < 0) {
91                 perror("setpriority");
92                 exit(1);
93             }
94         }
95         close(fds[1]);
96
97         /*
98          * Figure out how many loops it takes for 1 second's worth.
99          */
100         start_timing();
101         for (j = 0; ; ++j) {
102             if (write(fds[0], buf, bytes) != bytes) {
103                 perror("write");
104                 exit(1);
105             }
106             if ((j & 31) == 0 && stop_timing(0, NULL))
107                 break;
108         }
109         loops = j * 2 + 1;
110         usleep(1000000 / 10);
111         start_timing();
112
113         for (j = loops; j; --j) {
114             if (write(fds[0], buf, bytes) != bytes) {
115                 perror("write");
116                 exit(1);
117             }
118         }
119         close(fds[0]);
120         while(wait(NULL) >= 0)
121             ;
122         stop_timing(loops, "full duplex socketpair / %dK bufs:", bytes / 1024);
123         printf("%s: blkSize %d %5.2f MBytes/sec\n",
124                 msg,
125                 bytes,
126                 (double)loops * bytes * 1000000.0 /
127                 (1024.0 * 1024.0 * get_timing()));
128     }
129     return(0);
130 }