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