]>
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 | #pragma once | |
5 | ||
6 | #include "acconfig.h" | |
7 | #ifdef HAVE_LIBAIO | |
8 | # include <libaio.h> | |
9 | ||
10 | #include <boost/intrusive/list.hpp> | |
11 | #include <boost/container/small_vector.hpp> | |
12 | ||
13 | #include "include/buffer.h" | |
224ce89b | 14 | #include "include/types.h" |
7c673cae FG |
15 | |
16 | struct aio_t { | |
17 | struct iocb iocb; // must be first element; see shenanigans in aio_queue_t | |
18 | void *priv; | |
19 | int fd; | |
20 | boost::container::small_vector<iovec,4> iov; | |
21 | uint64_t offset, length; | |
22 | int rval; | |
23 | bufferlist bl; ///< write payload (so that it remains stable for duration) | |
24 | ||
25 | boost::intrusive::list_member_hook<> queue_item; | |
26 | ||
27 | aio_t(void *p, int f) : priv(p), fd(f), offset(0), length(0), rval(-1000) { | |
28 | } | |
29 | ||
30 | void pwritev(uint64_t _offset, uint64_t len) { | |
31 | offset = _offset; | |
32 | length = len; | |
33 | io_prep_pwritev(&iocb, fd, &iov[0], iov.size(), offset); | |
34 | } | |
35 | void pread(uint64_t _offset, uint64_t len) { | |
36 | offset = _offset; | |
37 | length = len; | |
38 | bufferptr p = buffer::create_page_aligned(length); | |
39 | io_prep_pread(&iocb, fd, p.c_str(), length, offset); | |
40 | bl.append(std::move(p)); | |
41 | } | |
42 | ||
43 | int get_return_value() { | |
44 | return rval; | |
45 | } | |
46 | }; | |
47 | ||
48 | typedef boost::intrusive::list< | |
49 | aio_t, | |
50 | boost::intrusive::member_hook< | |
51 | aio_t, | |
52 | boost::intrusive::list_member_hook<>, | |
53 | &aio_t::queue_item> > aio_list_t; | |
54 | ||
55 | struct aio_queue_t { | |
56 | int max_iodepth; | |
57 | io_context_t ctx; | |
58 | ||
224ce89b WB |
59 | typedef list<aio_t>::iterator aio_iter; |
60 | ||
7c673cae FG |
61 | explicit aio_queue_t(unsigned max_iodepth) |
62 | : max_iodepth(max_iodepth), | |
63 | ctx(0) { | |
64 | } | |
65 | ~aio_queue_t() { | |
66 | assert(ctx == 0); | |
67 | } | |
68 | ||
69 | int init() { | |
70 | assert(ctx == 0); | |
31f18b77 FG |
71 | int r = io_setup(max_iodepth, &ctx); |
72 | if (r < 0) { | |
73 | if (ctx) { | |
74 | io_destroy(ctx); | |
75 | ctx = 0; | |
76 | } | |
77 | } | |
78 | return r; | |
7c673cae FG |
79 | } |
80 | void shutdown() { | |
81 | if (ctx) { | |
82 | int r = io_destroy(ctx); | |
83 | assert(r == 0); | |
84 | ctx = 0; | |
85 | } | |
86 | } | |
87 | ||
88 | int submit(aio_t &aio, int *retries); | |
224ce89b WB |
89 | int submit_batch(aio_iter begin, aio_iter end, uint16_t aios_size, |
90 | void *priv, int *retries); | |
7c673cae FG |
91 | int get_next_completed(int timeout_ms, aio_t **paio, int max); |
92 | }; | |
93 | ||
94 | #endif |