bw_pipe.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * bw_pipe.c - pipe bandwidth benchmark.
  3. *
  4. * Usage: bw_pipe
  5. *
  6. * Copyright (c) 1994 Larry McVoy. Distributed under the FSF GPL with
  7. * additional restriction that results may published only if
  8. * (1) the benchmark is unmodified, and
  9. * (2) the version in the sccsid below is included in the report.
  10. * Support for this development by Sun Microsystems is gratefully acknowledged.
  11. */
  12. char *id = "$Id$\n";
  13. #include "bench.h"
  14. void reader(int controlfd, int pipefd, size_t bytes);
  15. void writer(int controlfd, int pipefd);
  16. size_t XFER = 10*1024*1024;
  17. int pid;
  18. char *buf;
  19. int
  20. main()
  21. {
  22. int pipes[2];
  23. int control[2];
  24. if (pipe(pipes) == -1) {
  25. perror("pipe");
  26. return(1);
  27. }
  28. if (pipe(control) == -1) {
  29. perror("pipe");
  30. return(1);
  31. }
  32. switch (pid = fork()) {
  33. case 0:
  34. close(control[1]);
  35. close(pipes[0]);
  36. buf = (char*)valloc(XFERSIZE);
  37. if (buf == NULL) {
  38. perror("no memory");
  39. return(1);
  40. }
  41. touch(buf, XFERSIZE);
  42. writer(control[0], pipes[1]);
  43. return(0);
  44. /*NOTREACHED*/
  45. case -1:
  46. perror("fork");
  47. return(1);
  48. /*NOTREACHED*/
  49. default:
  50. break;
  51. }
  52. close(control[0]);
  53. close(pipes[1]);
  54. buf = (char*)valloc(XFERSIZE + getpagesize());
  55. if (buf == NULL) {
  56. perror("no memory");
  57. return(1);
  58. }
  59. touch(buf, XFERSIZE + getpagesize());
  60. buf += 128; /* destroy page alignment */
  61. BENCH(reader(control[1], pipes[0], XFER), MEDIUM);
  62. fprintf(stderr, "Pipe bandwidth: ");
  63. mb(get_n() * XFER);
  64. kill(pid, 15);
  65. return(0);
  66. }
  67. void
  68. writer(int controlfd, int pipefd)
  69. {
  70. size_t todo;
  71. size_t bufsize = XFERSIZE;
  72. ssize_t n;
  73. for ( ;; ) {
  74. bufsize = XFERSIZE;
  75. n = read(controlfd, &todo, sizeof(todo));
  76. if (n < 0) perror("writer::read");
  77. while (todo > 0) {
  78. if (todo < bufsize) bufsize = todo;
  79. #ifdef TOUCH
  80. touch(buf, bufsize);
  81. #endif
  82. n = write(pipefd, buf, bufsize);
  83. if (n <= 0) {
  84. perror("writer::write");
  85. break;
  86. }
  87. todo -= n;
  88. }
  89. }
  90. }
  91. void
  92. reader(int controlfd, int pipefd, size_t bytes)
  93. {
  94. int done = 0;
  95. size_t todo = bytes;
  96. size_t bufsize = XFERSIZE;
  97. ssize_t n;
  98. n = write(controlfd, &bytes, sizeof(bytes));
  99. if (n < 0) perror("reader::write");
  100. while ((done < todo) && ((n = read(pipefd, buf, bufsize)) > 0)) {
  101. done += n;
  102. if (todo - done < bufsize) bufsize = todo - done;
  103. }
  104. if (n < 0) perror("reader::write");
  105. if (done < bytes) {
  106. fprintf(stderr, "reader: bytes=%ld, done=%d, todo=%ld\n", bytes, done, todo);
  107. }
  108. }