run-loop.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include <ccan/io/io.h>
  2. #include <ccan/time/time.h>
  3. #include <sys/wait.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <assert.h>
  7. #include <err.h>
  8. #include <signal.h>
  9. #define NUM 500
  10. #define NUM_ITERS 10000
  11. struct buffer {
  12. int iters;
  13. struct io_conn *reader, *writer;
  14. char buf[32];
  15. };
  16. static struct io_plan poke_writer(struct io_conn *conn, struct buffer *buf);
  17. static struct io_plan poke_reader(struct io_conn *conn, struct buffer *buf);
  18. static struct io_plan do_read(struct io_conn *conn, struct buffer *buf)
  19. {
  20. assert(conn == buf->reader);
  21. return io_read(conn, &buf->buf, sizeof(buf->buf), poke_writer, buf);
  22. }
  23. static struct io_plan do_write(struct io_conn *conn, struct buffer *buf)
  24. {
  25. assert(conn == buf->writer);
  26. return io_write(conn, &buf->buf, sizeof(buf->buf), poke_reader, buf);
  27. }
  28. static struct io_plan poke_writer(struct io_conn *conn, struct buffer *buf)
  29. {
  30. assert(conn == buf->reader);
  31. if (buf->iters == NUM_ITERS)
  32. return io_close(conn, NULL);
  33. /* You write. */
  34. io_wake(buf->writer, do_write, buf);
  35. /* I'll wait until you wake me. */
  36. return io_idle(conn);
  37. }
  38. static struct io_plan poke_reader(struct io_conn *conn, struct buffer *buf)
  39. {
  40. assert(conn == buf->writer);
  41. /* You read. */
  42. io_wake(buf->reader, do_read, buf);
  43. if (++buf->iters == NUM_ITERS)
  44. return io_close(conn, NULL);
  45. /* I'll wait until you tell me to write. */
  46. return io_idle(conn);
  47. }
  48. static struct io_plan reader(struct io_conn *conn, struct buffer *buf)
  49. {
  50. assert(conn == buf->reader);
  51. /* Wait for writer to tell us to read. */
  52. return io_idle(conn);
  53. }
  54. int main(void)
  55. {
  56. unsigned int i;
  57. int fds[2], last_read, last_write;
  58. struct timespec start, end;
  59. struct buffer buf[NUM];
  60. if (pipe(fds) != 0)
  61. err(1, "pipe");
  62. last_read = fds[0];
  63. last_write = fds[1];
  64. for (i = 1; i < NUM; i++) {
  65. buf[i].iters = 0;
  66. if (pipe(fds) < 0)
  67. err(1, "pipe");
  68. memset(buf[i].buf, i, sizeof(buf[i].buf));
  69. sprintf(buf[i].buf, "%i-%i", i, i);
  70. buf[i].reader = io_new_conn(last_read, reader, NULL, &buf[i]);
  71. if (!buf[i].reader)
  72. err(1, "Creating reader %i", i);
  73. buf[i].writer = io_new_conn(fds[1], do_write, NULL, &buf[i]);
  74. if (!buf[i].writer)
  75. err(1, "Creating writer %i", i);
  76. last_read = fds[0];
  77. }
  78. /* Last one completes the cirle. */
  79. i = 0;
  80. buf[i].iters = 0;
  81. sprintf(buf[i].buf, "%i-%i", i, i);
  82. buf[i].reader = io_new_conn(last_read, reader, NULL, &buf[i]);
  83. if (!buf[i].reader)
  84. err(1, "Creating reader %i", i);
  85. buf[i].writer = io_new_conn(last_write, do_write, NULL, &buf[i]);
  86. if (!buf[i].writer)
  87. err(1, "Creating writer %i", i);
  88. /* They should eventually exit */
  89. start = time_now();
  90. if (io_loop() != NULL)
  91. errx(1, "io_loop?");
  92. end = time_now();
  93. for (i = 0; i < NUM; i++) {
  94. char b[sizeof(buf[0].buf)];
  95. memset(b, i, sizeof(b));
  96. sprintf(b, "%i-%i", i, i);
  97. if (memcmp(b, buf[(i + NUM_ITERS) % NUM].buf, sizeof(b)) != 0)
  98. errx(1, "Buffer for %i was '%s' not '%s'",
  99. i, buf[(i + NUM_ITERS) % NUM].buf, b);
  100. }
  101. printf("run-many: %u %u iterations: %llu usec\n",
  102. NUM, NUM_ITERS, (long long)time_to_usec(time_sub(end, start)));
  103. return 0;
  104. }