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