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