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* get_user_data(const linux_abi::iocb& iocb);
101 void set_nowait(linux_abi::iocb& iocb, bool nowait);
103 void set_eventfd_notification(linux_abi::iocb& iocb, int eventfd);
105 linux_abi::iocb* get_iocb(const linux_abi::io_event& ioev);
107 int io_setup(int nr_events, linux_abi::aio_context_t* io_context);
108 int io_destroy(linux_abi::aio_context_t io_context) noexcept;
109 int io_submit(linux_abi::aio_context_t io_context, long nr, linux_abi::iocb** iocbs);
110 int io_cancel(linux_abi::aio_context_t io_context, linux_abi::iocb* iocb, linux_abi::io_event* result);
111 int io_getevents(linux_abi::aio_context_t io_context, long min_nr, long nr, linux_abi::io_event* events, const ::timespec* timeout,
112 bool force_syscall = false);
113 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,
114 bool force_syscall = false);
116 void setup_aio_context(size_t nr, linux_abi::aio_context_t* io_context);
120 extern bool aio_nowait_supported;
126 make_read_iocb(int fd, uint64_t offset, void* buffer, size_t len) {
127 linux_abi::iocb iocb{};
128 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PREAD;
129 iocb.aio_fildes = fd;
130 iocb.aio_offset = offset;
131 iocb.aio_buf = reinterpret_cast<uintptr_t>(buffer);
132 iocb.aio_nbytes = len;
138 make_write_iocb(int fd, uint64_t offset, const void* buffer, size_t len) {
139 linux_abi::iocb iocb{};
140 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PWRITE;
141 iocb.aio_fildes = fd;
142 iocb.aio_offset = offset;
143 iocb.aio_buf = reinterpret_cast<uintptr_t>(buffer);
144 iocb.aio_nbytes = len;
150 make_readv_iocb(int fd, uint64_t offset, const ::iovec* iov, size_t niov) {
151 linux_abi::iocb iocb{};
152 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PREADV;
153 iocb.aio_fildes = fd;
154 iocb.aio_offset = offset;
155 iocb.aio_buf = reinterpret_cast<uintptr_t>(iov);
156 iocb.aio_nbytes = niov;
162 make_writev_iocb(int fd, uint64_t offset, const ::iovec* iov, size_t niov) {
163 linux_abi::iocb iocb{};
164 iocb.aio_lio_opcode = linux_abi::iocb_cmd::PWRITEV;
165 iocb.aio_fildes = fd;
166 iocb.aio_offset = offset;
167 iocb.aio_buf = reinterpret_cast<uintptr_t>(iov);
168 iocb.aio_nbytes = niov;
174 make_poll_iocb(int fd, uint32_t events) {
175 linux_abi::iocb iocb{};
176 iocb.aio_lio_opcode = linux_abi::iocb_cmd::POLL;
177 iocb.aio_fildes = fd;
178 iocb.aio_buf = events;
184 make_fdsync_iocb(int fd) {
185 linux_abi::iocb iocb{};
186 iocb.aio_lio_opcode = linux_abi::iocb_cmd::FDSYNC;
187 iocb.aio_fildes = fd;
193 set_user_data(linux_abi::iocb& iocb, void* data) {
194 iocb.aio_data = reinterpret_cast<uintptr_t>(data);
199 get_user_data(const linux_abi::iocb& iocb) {
200 return reinterpret_cast<void*>(uintptr_t(iocb.aio_data));
205 set_eventfd_notification(linux_abi::iocb& iocb, int eventfd) {
206 iocb.aio_flags |= linux_abi::IOCB_FLAG_RESFD;
207 iocb.aio_resfd = eventfd;
212 get_iocb(const linux_abi::io_event& ev) {
213 return reinterpret_cast<linux_abi::iocb*>(uintptr_t(ev.obj));
218 set_nowait(linux_abi::iocb& iocb, bool nowait) {
220 if (aio_nowait_supported) {
222 iocb.aio_rw_flags |= RWF_NOWAIT;
224 iocb.aio_rw_flags &= ~RWF_NOWAIT;