source: libcfa/src/concurrency/iocall.cfa @ 920dca3

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 920dca3 was f00b26d4, checked in by Thierry Delisle <tdelisle@…>, 4 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.