source: libcfa/src/concurrency/iocall.cfa@ e660761

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since e660761 was f00b26d4, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Re-worked IO to use epoll and support multiple io_contexts per cluster.
Also redid how cluster options are handled.
Changed how iofwd calls are passed to support future features and io_contexts rework.

  • Property mode set to 100644
File size: 18.3 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2020 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// iocall.cfa --
8//
9// Author : Thierry Delisle
10// Created On : Wed Jul 1 14:51:00 2020
11// Last Modified By :
12// Last Modified On :
13// Update Count :
14//
15
16#include "bits/defs.hfa"
17
18//=============================================================================================
19// I/O uring backend
20//=============================================================================================
21
22#if defined(CFA_HAVE_LINUX_IO_URING_H)
23 #include <stdint.h>
24 #include <errno.h>
25 #include <linux/io_uring.h>
26
27 #include "kernel_private.hfa"
28
29 extern [* struct io_uring_sqe, uint32_t] __submit_alloc( struct __io_data & ring, uint64_t data );
30 extern void __submit( struct io_context * ctx, uint32_t idx ) __attribute__((nonnull (1)));
31
32 static inline void ?{}(struct io_uring_sqe & this, uint8_t opcode, int fd) {
33 this.opcode = opcode;
34 #if !defined(IOSQE_ASYNC)
35 this.flags = 0;
36 #else
37 this.flags = IOSQE_ASYNC;
38 #endif
39 this.ioprio = 0;
40 this.fd = fd;
41 this.off = 0;
42 this.addr = 0;
43 this.len = 0;
44 this.rw_flags = 0;
45 this.__pad2[0] = this.__pad2[1] = this.__pad2[2] = 0;
46 }
47
48 static inline void ?{}(struct io_uring_sqe & this, uint8_t opcode, int fd, void * addr, uint32_t len, uint64_t off ) {
49 (this){ opcode, fd };
50 this.off = off;
51 this.addr = (uint64_t)(uintptr_t)addr;
52 this.len = len;
53 }
54
55
56
57 #if defined(CFA_HAVE_IOSQE_FIXED_FILE) && defined(CFA_HAVE_IOSQE_IO_DRAIN) && defined(CFA_HAVE_IOSQE_ASYNC)
58 #define REGULAR_FLAGS (IOSQE_FIXED_FILE | IOSQE_IO_DRAIN | IOSQE_ASYNC)
59 #elif defined(CFA_HAVE_IOSQE_FIXED_FILE) && defined(CFA_HAVE_IOSQE_ASYNC)
60 #define REGULAR_FLAGS (IOSQE_FIXED_FILE | IOSQE_ASYNC)
61 #elif defined(CFA_HAVE_IOSQE_FIXED_FILE) && defined(CFA_HAVE_IOSQE_IO_DRAIN)
62 #define REGULAR_FLAGS (IOSQE_FIXED_FILE | IOSQE_IO_DRAIN)
63 #elif defined(CFA_HAVE_IOSQE_IO_DRAIN) && defined(CFA_HAVE_IOSQE_ASYNC)
64 #define REGULAR_FLAGS (IOSQE_IO_DRAIN | IOSQE_ASYNC)
65 #elif defined(CFA_HAVE_IOSQE_FIXED_FILE)
66 #define REGULAR_FLAGS (IOSQE_FIXED_FILE)
67 #elif defined(CFA_HAVE_IOSQE_IO_DRAIN)
68 #define REGULAR_FLAGS (IOSQE_IO_DRAIN)
69 #elif defined(CFA_HAVE_IOSQE_ASYNC)
70 #define REGULAR_FLAGS (IOSQE_ASYNC)
71 #else
72 #define REGULAR_FLAGS (0)
73 #endif
74
75 #if defined(CFA_HAVE_IOSQE_IO_LINK) && defined(CFA_HAVE_IOSQE_IO_HARDLINK)
76 #define LINK_FLAGS (IOSQE_IO_LINK | IOSQE_IO_HARDLINK)
77 #elif defined(CFA_HAVE_IOSQE_IO_LINK)
78 #define LINK_FLAGS (IOSQE_IO_LINK)
79 #elif defined(CFA_HAVE_IOSQE_IO_HARDLINK)
80 #define LINK_FLAGS (IOSQE_IO_HARDLINK)
81 #else
82 #define LINK_FLAGS (0)
83 #endif
84
85 #if defined(CFA_HAVE_SPLICE_F_FD_IN_FIXED)
86 #define SPLICE_FLAGS (SPLICE_F_FD_IN_FIXED)
87 #else
88 #define SPLICE_FLAGS (0)
89 #endif
90
91
92 #define __submit_prelude \
93 if( 0 != (submit_flags & LINK_FLAGS) ) { errno = ENOTSUP; return -1; } \
94 (void)timeout; (void)cancellation; \
95 if( !context ) context = __get_io_context(); \
96 __io_user_data_t data = { 0, active_thread() }; \
97 struct __io_data & ring = *context->thrd.ring; \
98 struct io_uring_sqe * sqe; \
99 uint32_t idx; \
100 [sqe, idx] = __submit_alloc( ring, (uint64_t)(uintptr_t)&data ); \
101 sqe->flags = REGULAR_FLAGS & submit_flags;
102
103 #define __submit_wait \
104 /*__cfaabi_bits_print_safe( STDERR_FILENO, "Preparing user data %p for %p\n", &data, data.thrd );*/ \
105 verify( sqe->user_data == (uint64_t)(uintptr_t)&data ); \
106 __submit( context, idx ); \
107 park( __cfaabi_dbg_ctx ); \
108 if( data.result < 0 ) { \
109 errno = -data.result; \
110 return -1; \
111 } \
112 return data.result;
113#endif
114
115//=============================================================================================
116// I/O Forwards
117//=============================================================================================
118#include <time.hfa>
119
120// Some forward declarations
121#include <errno.h>
122#include <unistd.h>
123
124extern "C" {
125 #include <sys/types.h>
126 #include <sys/socket.h>
127 #include <sys/syscall.h>
128
129#if defined(HAVE_PREADV2)
130 struct iovec;
131 extern ssize_t preadv2 (int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
132#endif
133#if defined(HAVE_PWRITEV2)
134 struct iovec;
135 extern ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
136#endif
137
138 extern int fsync(int fd);
139 extern int sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags);
140
141 struct msghdr;
142 struct sockaddr;
143 extern ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
144 extern ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
145 extern ssize_t send(int sockfd, const void *buf, size_t len, int flags);
146 extern ssize_t recv(int sockfd, void *buf, size_t len, int flags);
147 extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
148 extern int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
149
150 extern int fallocate(int fd, int mode, uint64_t offset, uint64_t len);
151 extern int posix_fadvise(int fd, uint64_t offset, uint64_t len, int advice);
152 extern int madvise(void *addr, size_t length, int advice);
153
154 extern int openat(int dirfd, const char *pathname, int flags, mode_t mode);
155 extern int close(int fd);
156
157 extern ssize_t read (int fd, void *buf, size_t count);
158
159 extern ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
160 extern ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);
161}
162
163//=============================================================================================
164// I/O Interface
165//=============================================================================================
166
167//-----------------------------------------------------------------------------
168// Asynchronous operations
169#if defined(HAVE_PREADV2)
170 ssize_t cfa_preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
171 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_READV)
172 return preadv2(fd, iov, iovcnt, offset, flags);
173 #else
174 __submit_prelude
175
176 (*sqe){ IORING_OP_READV, fd, iov, iovcnt, offset };
177
178 __submit_wait
179 #endif
180 }
181#endif
182
183#if defined(HAVE_PWRITEV2)
184 ssize_t cfa_pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
185 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_WRITEV)
186 return pwritev2(fd, iov, iovcnt, offset, flags);
187 #else
188 __submit_prelude
189
190 (*sqe){ IORING_OP_WRITEV, fd, iov, iovcnt, offset };
191
192 __submit_wait
193 #endif
194 }
195#endif
196
197int cfa_fsync(int fd, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
198 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_FSYNC)
199 return fsync(fd);
200 #else
201 __submit_prelude
202
203 (*sqe){ IORING_OP_FSYNC, fd };
204
205 __submit_wait
206 #endif
207}
208
209int cfa_sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
210 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SYNC_FILE_RANGE)
211 return sync_file_range(fd, offset, nbytes, flags);
212 #else
213 __submit_prelude
214
215 (*sqe){ IORING_OP_SYNC_FILE_RANGE, fd };
216 sqe->off = offset;
217 sqe->len = nbytes;
218 sqe->sync_range_flags = flags;
219
220 __submit_wait
221 #endif
222}
223
224
225ssize_t cfa_sendmsg(int sockfd, const struct msghdr *msg, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
226 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SENDMSG)
227 return sendmsg(sockfd, msg, flags);
228 #else
229 __submit_prelude
230
231 (*sqe){ IORING_OP_SENDMSG, sockfd, msg, 1, 0 };
232 sqe->msg_flags = flags;
233
234 __submit_wait
235 #endif
236}
237
238ssize_t cfa_recvmsg(int sockfd, struct msghdr *msg, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
239 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_RECVMSG)
240 return recvmsg(sockfd, msg, flags);
241 #else
242 __submit_prelude
243
244 (*sqe){ IORING_OP_RECVMSG, sockfd, msg, 1, 0 };
245 sqe->msg_flags = flags;
246
247 __submit_wait
248 #endif
249}
250
251ssize_t cfa_send(int sockfd, const void *buf, size_t len, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
252 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SEND)
253 return send( sockfd, buf, len, flags );
254 #else
255 __submit_prelude
256
257 (*sqe){ IORING_OP_SEND, sockfd };
258 sqe->addr = (uint64_t)buf;
259 sqe->len = len;
260 sqe->msg_flags = flags;
261
262 __submit_wait
263 #endif
264}
265
266ssize_t cfa_recv(int sockfd, void *buf, size_t len, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
267 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_RECV)
268 return recv( sockfd, buf, len, flags );
269 #else
270 __submit_prelude
271
272 (*sqe){ IORING_OP_RECV, sockfd };
273 sqe->addr = (uint64_t)buf;
274 sqe->len = len;
275 sqe->msg_flags = flags;
276
277 __submit_wait
278 #endif
279}
280
281int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
282 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_ACCEPT)
283 return accept4( sockfd, addr, addrlen, flags );
284 #else
285 __submit_prelude
286
287 (*sqe){ IORING_OP_ACCEPT, sockfd };
288 sqe->addr = addr;
289 sqe->addr2 = addrlen;
290 sqe->accept_flags = flags;
291
292 __submit_wait
293 #endif
294}
295
296int cfa_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
297 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_CONNECT)
298 return connect( sockfd, addr, addrlen );
299 #else
300 __submit_prelude
301
302 (*sqe){ IORING_OP_CONNECT, sockfd };
303 sqe->addr = (uint64_t)addr;
304 sqe->off = addrlen;
305
306 __submit_wait
307 #endif
308}
309
310int cfa_fallocate(int fd, int mode, uint64_t offset, uint64_t len, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
311 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_FALLOCATE)
312 return fallocate( fd, mode, offset, len );
313 #else
314 __submit_prelude
315
316 (*sqe){ IORING_OP_FALLOCATE, fd };
317 sqe->off = offset;
318 sqe->len = length;
319 sqe->mode = mode;
320
321 __submit_wait
322 #endif
323}
324
325int cfa_fadvise(int fd, uint64_t offset, uint64_t len, int advice, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
326 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_FADVISE)
327 return posix_fadvise( fd, offset, len, advice );
328 #else
329 __submit_prelude
330
331 (*sqe){ IORING_OP_FADVISE, fd };
332 sqe->off = (uint64_t)offset;
333 sqe->len = length;
334 sqe->fadvise_advice = advice;
335
336 __submit_wait
337 #endif
338}
339
340int cfa_madvise(void *addr, size_t length, int advice, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
341 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_MADVISE)
342 return madvise( addr, length, advice );
343 #else
344 __submit_prelude
345
346 (*sqe){ IORING_OP_MADVISE, 0 };
347 sqe->addr = (uint64_t)addr;
348 sqe->len = length;
349 sqe->fadvise_advice = advice;
350
351 __submit_wait
352 #endif
353}
354
355int cfa_openat(int dirfd, const char *pathname, int flags, mode_t mode, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
356 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_OPENAT)
357 return openat( dirfd, pathname, flags, mode );
358 #else
359 __submit_prelude
360
361 (*sqe){ IORING_OP_OPENAT, dirfd };
362 sqe->addr = (uint64_t)pathname;
363 sqe->open_flags = flags;
364 sqe->mode = mode;
365
366 __submit_wait
367 #endif
368}
369
370int cfa_close(int fd, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
371 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_CLOSE)
372 return close( fd );
373 #else
374 __submit_prelude
375
376 (*sqe){ IORING_OP_CLOSE, fd };
377
378 __submit_wait
379 #endif
380}
381
382// Forward declare in case it is not supported
383struct statx;
384int cfa_statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
385 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_STATX)
386 #if defined(__NR_statx)
387 return syscall( __NR_statx, dirfd, pathname, flags, mask, statxbuf );
388 #else
389 errno = ENOTSUP;
390 return -1;
391 #endif
392 #else
393 __submit_prelude
394
395 (*sqe){ IORING_OP_STATX, dirfd, pathname, mask, (uint64_t)statxbuf };
396 sqe->statx_flags = flags;
397
398 __submit_wait
399 #endif
400}
401
402ssize_t cfa_read(int fd, void *buf, size_t count, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
403 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_READ)
404 return read( fd, buf, count );
405 #else
406 __submit_prelude
407
408 (*sqe){ IORING_OP_READ, fd, buf, count, 0 };
409
410 __submit_wait
411 #endif
412}
413
414ssize_t cfa_write(int fd, void *buf, size_t count, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
415 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_WRITE)
416 return read( fd, buf, count );
417 #else
418 __submit_prelude
419
420 (*sqe){ IORING_OP_WRITE, fd, buf, count, 0 };
421
422 __submit_wait
423 #endif
424}
425
426ssize_t cfa_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
427 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SPLICE)
428 return splice( fd_in, off_in, fd_out, off_out, len, flags );
429 #else
430 __submit_prelude
431
432 (*sqe){ IORING_OP_SPLICE, fd_out, 0p, len, off_out };
433 sqe->splice_fd_in = fd_in;
434 sqe->splice_off_in = off_in;
435 sqe->splice_flags = flags | (SPLICE_FLAGS & submit_flags);
436
437 __submit_wait
438 #endif
439}
440
441ssize_t cfa_tee(int fd_in, int fd_out, size_t len, unsigned int flags, int submit_flags, Duration timeout, io_cancellation * cancellation, io_context * context) {
442 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_TEE)
443 return tee( fd_in, fd_out, len, flags );
444 #else
445 __submit_prelude
446
447 (*sqe){ IORING_OP_TEE, fd_out, 0p, len, 0 };
448 sqe->splice_fd_in = fd_in;
449 sqe->splice_flags = flags | (SPLICE_FLAGS & submit_flags);
450
451 __submit_wait
452 #endif
453}
454
455//-----------------------------------------------------------------------------
456// Check if a function is asynchronous
457
458// Macro magic to reduce the size of the following switch case
459#define IS_DEFINED_APPLY(f, ...) f(__VA_ARGS__)
460#define IS_DEFINED_SECOND(first, second, ...) second
461#define IS_DEFINED_TEST(expansion) _CFA_IO_FEATURE_##expansion
462#define IS_DEFINED(macro) IS_DEFINED_APPLY( IS_DEFINED_SECOND,IS_DEFINED_TEST(macro) false, true)
463
464bool has_user_level_blocking( fptr_t func ) {
465 #if defined(CFA_HAVE_LINUX_IO_URING_H)
466 #if defined(HAVE_PREADV2)
467 if( /*func == (fptr_t)preadv2 || */
468 func == (fptr_t)cfa_preadv2 )
469 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_READV ,
470 return IS_DEFINED(CFA_HAVE_IORING_OP_READV);
471 #endif
472
473 #if defined(HAVE_PWRITEV2)
474 if( /*func == (fptr_t)pwritev2 || */
475 func == (fptr_t)cfa_pwritev2 )
476 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_WRITEV ,
477 return IS_DEFINED(CFA_HAVE_IORING_OP_WRITEV);
478 #endif
479
480 if( /*func == (fptr_t)fsync || */
481 func == (fptr_t)cfa_fsync )
482 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_FSYNC ,
483 return IS_DEFINED(CFA_HAVE_IORING_OP_FSYNC);
484
485 if( /*func == (fptr_t)ync_file_range || */
486 func == (fptr_t)cfa_sync_file_range )
487 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SYNC_FILE_RANGE ,
488 return IS_DEFINED(CFA_HAVE_IORING_OP_SYNC_FILE_RANGE);
489
490 if( /*func == (fptr_t)sendmsg || */
491 func == (fptr_t)cfa_sendmsg )
492 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SENDMSG ,
493 return IS_DEFINED(CFA_HAVE_IORING_OP_SENDMSG);
494
495 if( /*func == (fptr_t)recvmsg || */
496 func == (fptr_t)cfa_recvmsg )
497 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_RECVMSG ,
498 return IS_DEFINED(CFA_HAVE_IORING_OP_RECVMSG);
499
500 if( /*func == (fptr_t)send || */
501 func == (fptr_t)cfa_send )
502 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SEND ,
503 return IS_DEFINED(CFA_HAVE_IORING_OP_SEND);
504
505 if( /*func == (fptr_t)recv || */
506 func == (fptr_t)cfa_recv )
507 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_RECV ,
508 return IS_DEFINED(CFA_HAVE_IORING_OP_RECV);
509
510 if( /*func == (fptr_t)accept4 || */
511 func == (fptr_t)cfa_accept4 )
512 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_ACCEPT ,
513 return IS_DEFINED(CFA_HAVE_IORING_OP_ACCEPT);
514
515 if( /*func == (fptr_t)connect || */
516 func == (fptr_t)cfa_connect )
517 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_CONNECT ,
518 return IS_DEFINED(CFA_HAVE_IORING_OP_CONNECT);
519
520 if( /*func == (fptr_t)fallocate || */
521 func == (fptr_t)cfa_fallocate )
522 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_FALLOCATE ,
523 return IS_DEFINED(CFA_HAVE_IORING_OP_FALLOCATE);
524
525 if( /*func == (fptr_t)posix_fadvise || */
526 func == (fptr_t)cfa_fadvise )
527 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_FADVISE ,
528 return IS_DEFINED(CFA_HAVE_IORING_OP_FADVISE);
529
530 if( /*func == (fptr_t)madvise || */
531 func == (fptr_t)cfa_madvise )
532 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_MADVISE ,
533 return IS_DEFINED(CFA_HAVE_IORING_OP_MADVISE);
534
535 if( /*func == (fptr_t)openat || */
536 func == (fptr_t)cfa_openat )
537 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_OPENAT ,
538 return IS_DEFINED(CFA_HAVE_IORING_OP_OPENAT);
539
540 if( /*func == (fptr_t)close || */
541 func == (fptr_t)cfa_close )
542 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_CLOSE ,
543 return IS_DEFINED(CFA_HAVE_IORING_OP_CLOSE);
544
545 if( /*func == (fptr_t)read || */
546 func == (fptr_t)cfa_read )
547 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_READ ,
548 return IS_DEFINED(CFA_HAVE_IORING_OP_READ);
549
550 if( /*func == (fptr_t)write || */
551 func == (fptr_t)cfa_write )
552 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_WRITE ,
553 return IS_DEFINED(CFA_HAVE_IORING_OP_WRITE);
554
555 if( /*func == (fptr_t)splice || */
556 func == (fptr_t)cfa_splice )
557 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SPLICE ,
558 return IS_DEFINED(CFA_HAVE_IORING_OP_SPLICE);
559
560 if( /*func == (fptr_t)tee || */
561 func == (fptr_t)cfa_tee )
562 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_TEE ,
563 return IS_DEFINED(CFA_HAVE_IORING_OP_TEE);
564 #endif
565
566 return false;
567}
Note: See TracBrowser for help on using the repository browser.