2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
19 * Copyright (C) 2017 ScyllaDB
36 using aio_context_t = unsigned long;
38 enum class iocb_cmd : uint16_t {
56 constexpr int IOCB_FLAG_RESFD = 1;
61 #if __BYTE_ORDER == __LITTLE_ENDIAN
64 #elif __BYTE_ORDER == __BIG_ENDIAN
71 iocb_cmd aio_lio_opcode;
79 uint64_t aio_reserved2;
87 const sigset_t *sigmask;
93 linux_abi::iocb make_read_iocb(int fd, uint64_t offset, void* buffer, size_t len);
94 linux_abi::iocb make_write_iocb(int fd, uint64_t offset, const void* buffer, size_t len);
95 linux_abi::iocb make_readv_iocb(int fd, uint64_t offset, const ::iovec* iov, size_t niov);
96 linux_abi::iocb make_writev_iocb(int fd, uint64_t offset, const ::iovec* iov, size_t niov);
97 linux_abi::iocb make_poll_iocb(int fd, uint32_t events);
99 void set_user_data(linux_abi::iocb& iocb, void* data);
100 void set_nowait(linux_abi::iocb& iocb, bool nowait);
102 void set_eventfd_notification(linux_abi::iocb& iocb, int eventfd);
104 linux_abi::iocb* get_iocb(const linux_abi::io_event& ioev);
106 int io_setup(int nr_events, linux_abi::aio_context_t* io_context);
107 int io_destroy(linux_abi::aio_context_t io_context) noexcept;
108 int io_submit(linux_abi::aio_context_t io_context, long nr, linux_abi::iocb** iocbs);
109 int io_cancel(linux_abi::aio_context_t io_context, linux_abi::iocb* iocb, linux_abi::io_event* result);
110 int io_getevents(linux_abi::aio_context_t io_context, long min_nr, long nr, linux_abi::io_event* events, const ::timespec* timeout,
111 bool force_syscall = false);
112 int io_pgetevents(linux_abi::aio_context_t io_context, long min_nr, long nr, linux_abi::io_event* events, const ::timespec* timeout, const sigset_t* sigmask,
113 bool force_syscall = false);
115 void setup_aio_context(size_t nr, linux_abi::aio_context_t* io_context);
119 extern bool aio_nowait_supported;
125 make_read_iocb(int fd, uint64_t offset, void* buffer, size_t len) {
126 linux_abi::iocb iocb{};
127 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PREAD;
128 iocb.aio_fildes = fd;
129 iocb.aio_offset = offset;
130 iocb.aio_buf = reinterpret_cast<uintptr_t>(buffer);
131 iocb.aio_nbytes = len;
137 make_write_iocb(int fd, uint64_t offset, const void* buffer, size_t len) {
138 linux_abi::iocb iocb{};
139 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PWRITE;
140 iocb.aio_fildes = fd;
141 iocb.aio_offset = offset;
142 iocb.aio_buf = reinterpret_cast<uintptr_t>(buffer);
143 iocb.aio_nbytes = len;
149 make_readv_iocb(int fd, uint64_t offset, const ::iovec* iov, size_t niov) {
150 linux_abi::iocb iocb{};
151 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PREADV;
152 iocb.aio_fildes = fd;
153 iocb.aio_offset = offset;
154 iocb.aio_buf = reinterpret_cast<uintptr_t>(iov);
155 iocb.aio_nbytes = niov;
161 make_writev_iocb(int fd, uint64_t offset, const ::iovec* iov, size_t niov) {
162 linux_abi::iocb iocb{};
163 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PWRITEV;
164 iocb.aio_fildes = fd;
165 iocb.aio_offset = offset;
166 iocb.aio_buf = reinterpret_cast<uintptr_t>(iov);
167 iocb.aio_nbytes = niov;
173 make_poll_iocb(int fd, uint32_t events) {
174 linux_abi::iocb iocb{};
175 iocb.aio_lio_opcode = linux_abi::iocb_cmd::POLL;
176 iocb.aio_fildes = fd;
177 iocb.aio_buf = events;
183 make_fdsync_iocb(int fd) {
184 linux_abi::iocb iocb{};
185 iocb.aio_lio_opcode = linux_abi::iocb_cmd::FDSYNC;
186 iocb.aio_fildes = fd;
192 set_user_data(linux_abi::iocb& iocb, void* data) {
193 iocb.aio_data = reinterpret_cast<uintptr_t>(data);
196 template <typename T>
197 inline T* get_user_data(const linux_abi::iocb& iocb) noexcept {
198 return reinterpret_cast<T*>(uintptr_t(iocb.aio_data));
201 template <typename T>
202 inline T* get_user_data(const linux_abi::io_event& ev) noexcept {
203 return reinterpret_cast<T*>(uintptr_t(ev.data));
208 set_eventfd_notification(linux_abi::iocb& iocb, int eventfd) {
209 iocb.aio_flags |= linux_abi::IOCB_FLAG_RESFD;
210 iocb.aio_resfd = eventfd;
215 get_iocb(const linux_abi::io_event& ev) {
216 return reinterpret_cast<linux_abi::iocb*>(uintptr_t(ev.obj));
221 set_nowait(linux_abi::iocb& iocb, bool nowait) {
223 if (aio_nowait_supported) {
225 iocb.aio_rw_flags |= RWF_NOWAIT;
227 iocb.aio_rw_flags &= ~RWF_NOWAIT;