Merge from vendor branch TNFTP:
[dragonfly.git] / test / sysperf / pipe2.c
1 /*
2  * pipe2.c
3  *
4  * $DragonFly: src/test/sysperf/pipe2.c,v 1.5 2004/04/29 16:05:21 dillon Exp $
5  */
6
7 #include "blib.h"
8 #include <sys/resource.h>
9
10 #define PAGE_SIZE       4096
11 #define PAGE_MASK       (PAGE_SIZE - 1)
12
13 int
14 main(int ac, char **av)
15 {
16     long long count = 0;
17     long long max;
18     char c;
19     int j;
20     int loops;
21     int bytes;
22     int ppri = 999;
23     int fds[2];
24     char *buf;
25     char *ptr;
26     char *msg = "datarate";
27
28     if (ac == 1) {
29         fprintf(stderr, "%s blocksize[k,m] [pipe_writer_pri] [msg]\n", av[0]);
30         exit(1);
31     }
32     bytes = strtol(av[1], &ptr, 0);
33     if (*ptr == 'k' || *ptr == 'K') {
34         bytes *= 1024;
35     } else if (*ptr == 'm' || *ptr == 'M') {
36         bytes *= 1024 * 1024;
37     } else if (*ptr) {
38         fprintf(stderr, "Illegal numerical suffix: %s\n", ptr);
39         exit(1);
40     }
41     if (bytes <= 0) {
42         fprintf(stderr, "I can't handle %d sized buffers\n", bytes);
43         exit(1);
44     }
45     if (ac >= 3)
46         ppri = strtol(av[2], NULL, 0);
47     if (ac >= 4)
48         msg = av[3];
49
50     buf = mmap(NULL, bytes * 2 + PAGE_SIZE, 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         usleep(1000000 / 10);
109         start_timing();
110
111         for (j = loops; j; --j) {
112             if (write(fds[0], buf, bytes) != bytes) {
113                 perror("write");
114                 exit(1);
115             }
116         }
117         close(fds[0]);
118         while(wait(NULL) >= 0)
119             ;
120         stop_timing(loops, "full duplex pipe / %dK bufs:", bytes / 1024);
121         printf("%s: blkSize %d %5.2f MBytes/sec\n",
122                 msg,
123                 bytes,
124                 (double)loops * bytes * 1000000.0 / 
125                 (1024.0 * 1024.0 * get_timing()));
126     }
127     return(0);
128 }
129