]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include "aio.h" | |
5 | ||
6 | #if defined(HAVE_LIBAIO) | |
7 | ||
224ce89b | 8 | |
7c673cae FG |
9 | int aio_queue_t::submit(aio_t &aio, int *retries) |
10 | { | |
11 | // 2^16 * 125us = ~8 seconds, so max sleep is ~16 seconds | |
12 | int attempts = 16; | |
13 | int delay = 125; | |
14 | iocb *piocb = &aio.iocb; | |
224ce89b | 15 | int r; |
7c673cae | 16 | while (true) { |
224ce89b | 17 | r = io_submit(ctx, 1, &piocb); |
7c673cae FG |
18 | if (r < 0) { |
19 | if (r == -EAGAIN && attempts-- > 0) { | |
20 | usleep(delay); | |
21 | delay *= 2; | |
22 | (*retries)++; | |
23 | continue; | |
24 | } | |
7c673cae FG |
25 | } |
26 | assert(r == 1); | |
27 | break; | |
28 | } | |
224ce89b WB |
29 | return r; |
30 | } | |
31 | ||
32 | int aio_queue_t::submit_batch(aio_iter begin, aio_iter end, | |
33 | uint16_t aios_size, void *priv, | |
34 | int *retries) | |
35 | { | |
36 | // 2^16 * 125us = ~8 seconds, so max sleep is ~16 seconds | |
37 | int attempts = 16; | |
38 | int delay = 125; | |
39 | ||
40 | aio_iter cur = begin; | |
41 | struct iocb *piocb[aios_size]; | |
181888fb | 42 | int left = 0; |
224ce89b WB |
43 | while (cur != end) { |
44 | cur->priv = priv; | |
181888fb FG |
45 | *(piocb+left) = &cur->iocb; |
46 | ++left; | |
224ce89b WB |
47 | ++cur; |
48 | } | |
181888fb FG |
49 | int done = 0; |
50 | while (left > 0) { | |
51 | int r = io_submit(ctx, left, piocb + done); | |
224ce89b WB |
52 | if (r < 0) { |
53 | if (r == -EAGAIN && attempts-- > 0) { | |
54 | usleep(delay); | |
55 | delay *= 2; | |
56 | (*retries)++; | |
57 | continue; | |
58 | } | |
181888fb | 59 | return r; |
224ce89b | 60 | } |
181888fb FG |
61 | assert(r > 0); |
62 | done += r; | |
63 | left -= r; | |
224ce89b | 64 | } |
181888fb | 65 | return done; |
7c673cae FG |
66 | } |
67 | ||
68 | int aio_queue_t::get_next_completed(int timeout_ms, aio_t **paio, int max) | |
69 | { | |
70 | io_event event[max]; | |
71 | struct timespec t = { | |
72 | timeout_ms / 1000, | |
73 | (timeout_ms % 1000) * 1000 * 1000 | |
74 | }; | |
75 | ||
76 | int r = 0; | |
77 | do { | |
78 | r = io_getevents(ctx, 1, max, event, &t); | |
79 | } while (r == -EINTR); | |
80 | ||
81 | for (int i=0; i<r; ++i) { | |
82 | paio[i] = (aio_t *)event[i].obj; | |
83 | paio[i]->rval = event[i].res; | |
84 | } | |
85 | return r; | |
86 | } | |
87 | ||
88 | #endif |