#include <sys/types.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include "blib.h"
#define PAGE_SIZE 4096
#define PAGE_MASK (PAGE_SIZE - 1)
int
main(int ac, char **av)
{
long long count = 0;
long long max;
char c;
int j;
int loops;
int bytes;
int ppri = 999;
int fds[2];
char *buf;
char *ptr;
char *msg = "datarate";
if (ac == 1) {
fprintf(stderr, "%s blocksize[k,m] [pipe_writer_pri] [msg]\n", av[0]);
exit(1);
}
bytes = strtol(av[1], &ptr, 0);
if (*ptr == 'k' || *ptr == 'K') {
bytes *= 1024;
} else if (*ptr == 'm' || *ptr == 'M') {
bytes *= 1024 * 1024;
} else if (*ptr) {
fprintf(stderr, "Illegal numerical suffix: %s\n", ptr);
exit(1);
}
if (bytes <= 0) {
fprintf(stderr, "I can't handle %d sized buffers\n", bytes);
exit(1);
}
if (ac >= 3)
ppri = strtol(av[2], NULL, 0);
if (ac >= 4)
msg = av[3];
buf = mmap(NULL, bytes * 2 + PAGE_SIZE,
PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
if (buf == MAP_FAILED) {
perror("mmap/buffer");
exit(1);
}
bzero(buf, bytes * 2 + PAGE_SIZE);
printf("tests one-way pipe using direct-write buffer\n");
if (pipe(fds)) {
perror("pipe");
exit(1);
}
if (fork() == 0) {
int n;
int i;
close(fds[0]);
buf += (bytes + PAGE_MASK) & ~PAGE_MASK;
i = 0;
for (;;) {
n = read(fds[1], buf + i, bytes - i);
if (n <= 0)
break;
if (n + i == bytes)
i = 0;
else
i += n;
}
_exit(0);
} else {
if (ppri != 999) {
if (setpriority(PRIO_PROCESS, getpid(), ppri) < 0) {
perror("setpriority");
exit(1);
}
}
close(fds[1]);
start_timing();
for (j = 0; ; ++j) {
if (write(fds[0], buf, bytes) != bytes) {
perror("write");
exit(1);
}
if ((j & 31) == 0 && stop_timing(0, NULL))
break;
}
loops = j * 2 + 1;
loops *= 2;
usleep(1000000 / 10);
start_timing();
for (j = loops; j; --j) {
if (write(fds[0], buf, bytes) != bytes) {
perror("write");
exit(1);
}
}
close(fds[0]);
while(wait(NULL) >= 0)
;
stop_timing(loops, "full duplex pipe / %dK bufs:", bytes / 1024);
printf("%s: blkSize %d %5.2f MBytes/sec\n",
msg,
bytes,
(double)loops * bytes * 1000000.0 /
(1024.0 * 1024.0 * get_timing()));
}
return(0);
}