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