Changeset 4b84e35 for libcfa


Ignore:
Timestamp:
Jul 1, 2020, 3:27:59 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
5877b3e
Parents:
4ec028d
Message:

Fixed iocall

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/iocall.cfa

    r4ec028d r4b84e35  
    1414//
    1515
     16//=============================================================================================
     17// I/O uring backend
     18//=============================================================================================
     19
    1620#if defined(HAVE_LINUX_IO_URING_H)
    1721        #include <stdint.h>
     
    2327        extern void __submit( struct __io_data & ring, uint32_t idx );
    2428
    25 //=============================================================================================
    26 // I/O Interface
    27 //=============================================================================================
     29        static inline void ?{}(struct io_uring_sqe & this, uint8_t opcode, int fd) {
     30                this.opcode = opcode;
     31                #if !defined(IOSQE_ASYNC)
     32                        this.flags = 0;
     33                #else
     34                        this.flags = IOSQE_ASYNC;
     35                #endif
     36                this.ioprio = 0;
     37                this.fd = fd;
     38                this.off = 0;
     39                this.addr = 0;
     40                this.len = 0;
     41                this.rw_flags = 0;
     42                this.__pad2[0] = this.__pad2[1] = this.__pad2[2] = 0;
     43        }
     44
     45        static inline void ?{}(struct io_uring_sqe & this, uint8_t opcode, int fd, void * addr, uint32_t len, uint64_t off ) {
     46                (this){ opcode, fd };
     47                this.off = off;
     48                this.addr = (uint64_t)(uintptr_t)addr;
     49                this.len = len;
     50        }
    2851
    2952        #define __submit_prelude \
     
    4063                park( __cfaabi_dbg_ctx ); \
    4164                return data.result;
    42         #endif
    43 
    44         // Some forward declarations
    45         #include <unistd.h>
    46 
    47         extern "C" {
    48                 #include <sys/types.h>
    49                 #include <sys/socket.h>
    50                 #include <sys/syscall.h>
    51 
    52         #if defined(HAVE_PREADV2)
    53                 struct iovec;
    54                 extern ssize_t preadv2 (int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
    55         #endif
    56         #if defined(HAVE_PWRITEV2)
    57                 struct iovec;
    58                 extern ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
    59         #endif
    60 
    61                 extern int fsync(int fd);
    62                 extern int sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags);
    63 
    64                 struct msghdr;
    65                 struct sockaddr;
    66                 extern ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
    67                 extern ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
    68                 extern ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    69                 extern ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    70                 extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
    71                 extern int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    72 
    73                 extern int fallocate(int fd, int mode, uint64_t offset, uint64_t len);
    74                 extern int posix_fadvise(int fd, uint64_t offset, uint64_t len, int advice);
    75                 extern int madvise(void *addr, size_t length, int advice);
    76 
    77                 extern int openat(int dirfd, const char *pathname, int flags, mode_t mode);
    78                 extern int close(int fd);
    79 
    80                 extern ssize_t read (int fd, void *buf, size_t count);
    81         }
    82 
    83         //-----------------------------------------------------------------------------
    84         // Asynchronous operations
    85         #if defined(HAVE_PREADV2)
    86                 ssize_t cfa_preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) {
    87                         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READV)
    88                                 return preadv2(fd, iov, iovcnt, offset, flags);
    89                         #else
    90                                 __submit_prelude
    91 
    92                                 (*sqe){ IORING_OP_READV, fd, iov, iovcnt, offset };
    93 
    94                                 __submit_wait
    95                         #endif
    96                 }
    97         #endif
    98 
    99         #if defined(HAVE_PWRITEV2)
    100                 ssize_t cfa_pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) {
    101                         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_WRITEV)
    102                                 return pwritev2(fd, iov, iovcnt, offset, flags);
    103                         #else
    104                                 __submit_prelude
    105 
    106                                 (*sqe){ IORING_OP_WRITEV, fd, iov, iovcnt, offset };
    107 
    108                                 __submit_wait
    109                         #endif
    110                 }
    111         #endif
    112 
    113         int cfa_fsync(int fd) {
    114                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FSYNC)
    115                         return fsync(fd);
     65#endif
     66
     67//=============================================================================================
     68// I/O Forwards
     69//=============================================================================================
     70
     71// Some forward declarations
     72#include <unistd.h>
     73
     74extern "C" {
     75        #include <sys/types.h>
     76        #include <sys/socket.h>
     77        #include <sys/syscall.h>
     78
     79#if defined(HAVE_PREADV2)
     80        struct iovec;
     81        extern ssize_t preadv2 (int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
     82#endif
     83#if defined(HAVE_PWRITEV2)
     84        struct iovec;
     85        extern ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
     86#endif
     87
     88        extern int fsync(int fd);
     89        extern int sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags);
     90
     91        struct msghdr;
     92        struct sockaddr;
     93        extern ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
     94        extern ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
     95        extern ssize_t send(int sockfd, const void *buf, size_t len, int flags);
     96        extern ssize_t recv(int sockfd, void *buf, size_t len, int flags);
     97        extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
     98        extern int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
     99
     100        extern int fallocate(int fd, int mode, uint64_t offset, uint64_t len);
     101        extern int posix_fadvise(int fd, uint64_t offset, uint64_t len, int advice);
     102        extern int madvise(void *addr, size_t length, int advice);
     103
     104        extern int openat(int dirfd, const char *pathname, int flags, mode_t mode);
     105        extern int close(int fd);
     106
     107        extern ssize_t read (int fd, void *buf, size_t count);
     108}
     109
     110//=============================================================================================
     111// I/O Interface
     112//=============================================================================================
     113
     114//-----------------------------------------------------------------------------
     115// Asynchronous operations
     116#if defined(HAVE_PREADV2)
     117        ssize_t cfa_preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) {
     118                #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READV)
     119                        return preadv2(fd, iov, iovcnt, offset, flags);
    116120                #else
    117121                        __submit_prelude
    118122
    119                         (*sqe){ IORING_OP_FSYNC, fd };
     123                        (*sqe){ IORING_OP_READV, fd, iov, iovcnt, offset };
    120124
    121125                        __submit_wait
    122126                #endif
    123127        }
    124 
    125         int cfa_sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags) {
    126                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SYNC_FILE_RANGE)
    127                         return sync_file_range(fd, offset, nbytes, flags);
     128#endif
     129
     130#if defined(HAVE_PWRITEV2)
     131        ssize_t cfa_pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) {
     132                #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_WRITEV)
     133                        return pwritev2(fd, iov, iovcnt, offset, flags);
    128134                #else
    129135                        __submit_prelude
    130136
    131                         (*sqe){ IORING_OP_SYNC_FILE_RANGE, fd };
    132                         sqe->off = offset;
    133                         sqe->len = nbytes;
    134                         sqe->sync_range_flags = flags;
     137                        (*sqe){ IORING_OP_WRITEV, fd, iov, iovcnt, offset };
    135138
    136139                        __submit_wait
    137140                #endif
    138141        }
    139 
    140 
    141         ssize_t cfa_sendmsg(int sockfd, const struct msghdr *msg, int flags) {
    142                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SENDMSG)
    143                         return sendmsg(sockfd, msg, flags);
    144                 #else
    145                         __submit_prelude
    146 
    147                         (*sqe){ IORING_OP_SENDMSG, sockfd, msg, 1, 0 };
    148                         sqe->msg_flags = flags;
    149 
    150                         __submit_wait
     142#endif
     143
     144int cfa_fsync(int fd) {
     145        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FSYNC)
     146                return fsync(fd);
     147        #else
     148                __submit_prelude
     149
     150                (*sqe){ IORING_OP_FSYNC, fd };
     151
     152                __submit_wait
     153        #endif
     154}
     155
     156int cfa_sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags) {
     157        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SYNC_FILE_RANGE)
     158                return sync_file_range(fd, offset, nbytes, flags);
     159        #else
     160                __submit_prelude
     161
     162                (*sqe){ IORING_OP_SYNC_FILE_RANGE, fd };
     163                sqe->off = offset;
     164                sqe->len = nbytes;
     165                sqe->sync_range_flags = flags;
     166
     167                __submit_wait
     168        #endif
     169}
     170
     171
     172ssize_t cfa_sendmsg(int sockfd, const struct msghdr *msg, int flags) {
     173        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SENDMSG)
     174                return sendmsg(sockfd, msg, flags);
     175        #else
     176                __submit_prelude
     177
     178                (*sqe){ IORING_OP_SENDMSG, sockfd, msg, 1, 0 };
     179                sqe->msg_flags = flags;
     180
     181                __submit_wait
     182        #endif
     183}
     184
     185ssize_t cfa_recvmsg(int sockfd, struct msghdr *msg, int flags) {
     186        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_RECVMSG)
     187                return recvmsg(sockfd, msg, flags);
     188        #else
     189                __submit_prelude
     190
     191                (*sqe){ IORING_OP_RECVMSG, sockfd, msg, 1, 0 };
     192                sqe->msg_flags = flags;
     193
     194                __submit_wait
     195        #endif
     196}
     197
     198ssize_t cfa_send(int sockfd, const void *buf, size_t len, int flags) {
     199        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SEND)
     200                return send( sockfd, buf, len, flags );
     201        #else
     202                __submit_prelude
     203
     204                (*sqe){ IORING_OP_SEND, sockfd };
     205                sqe->addr = (uint64_t)buf;
     206                sqe->len = len;
     207                sqe->msg_flags = flags;
     208
     209                __submit_wait
     210        #endif
     211}
     212
     213ssize_t cfa_recv(int sockfd, void *buf, size_t len, int flags) {
     214        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_RECV)
     215                return recv( sockfd, buf, len, flags );
     216        #else
     217                __submit_prelude
     218
     219                (*sqe){ IORING_OP_RECV, sockfd };
     220                sqe->addr = (uint64_t)buf;
     221                sqe->len = len;
     222                sqe->msg_flags = flags;
     223
     224                __submit_wait
     225        #endif
     226}
     227
     228int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
     229        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_ACCEPT)
     230                return accept4( sockfd, addr, addrlen, flags );
     231        #else
     232                __submit_prelude
     233
     234                (*sqe){ IORING_OP_ACCEPT, sockfd };
     235                sqe->addr = addr;
     236                sqe->addr2 = addrlen;
     237                sqe->accept_flags = flags;
     238
     239                __submit_wait
     240        #endif
     241}
     242
     243int cfa_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
     244        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_CONNECT)
     245                return connect( sockfd, addr, addrlen );
     246        #else
     247                __submit_prelude
     248
     249                (*sqe){ IORING_OP_CONNECT, sockfd };
     250                sqe->addr = (uint64_t)addr;
     251                sqe->off = addrlen;
     252
     253                __submit_wait
     254        #endif
     255}
     256
     257int cfa_fallocate(int fd, int mode, uint64_t offset, uint64_t len) {
     258        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FALLOCATE)
     259                return fallocate( fd, mode, offset, len );
     260        #else
     261                __submit_prelude
     262
     263                (*sqe){ IORING_OP_FALLOCATE, fd };
     264                sqe->off = offset;
     265                sqe->len = length;
     266                sqe->mode = mode;
     267
     268                __submit_wait
     269        #endif
     270}
     271
     272int cfa_fadvise(int fd, uint64_t offset, uint64_t len, int advice) {
     273        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FADVISE)
     274                return posix_fadvise( fd, offset, len, advice );
     275        #else
     276                __submit_prelude
     277
     278                (*sqe){ IORING_OP_FADVISE, fd };
     279                sqe->off = (uint64_t)offset;
     280                sqe->len = length;
     281                sqe->fadvise_advice = advice;
     282
     283                __submit_wait
     284        #endif
     285}
     286
     287int cfa_madvise(void *addr, size_t length, int advice) {
     288        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_MADVISE)
     289                return madvise( addr, length, advice );
     290        #else
     291                __submit_prelude
     292
     293                (*sqe){ IORING_OP_MADVISE, 0 };
     294                sqe->addr = (uint64_t)addr;
     295                sqe->len = length;
     296                sqe->fadvise_advice = advice;
     297
     298                __submit_wait
     299        #endif
     300}
     301
     302int cfa_openat(int dirfd, const char *pathname, int flags, mode_t mode) {
     303        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_OPENAT)
     304                return openat( dirfd, pathname, flags, mode );
     305        #else
     306                __submit_prelude
     307
     308                (*sqe){ IORING_OP_OPENAT, dirfd };
     309                sqe->addr = (uint64_t)pathname;
     310                sqe->open_flags = flags;
     311                sqe->mode = mode;
     312
     313                __submit_wait
     314        #endif
     315}
     316
     317int cfa_close(int fd) {
     318        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_CLOSE)
     319                return close( fd );
     320        #else
     321                __submit_prelude
     322
     323                (*sqe){ IORING_OP_CLOSE, fd };
     324
     325                __submit_wait
     326        #endif
     327}
     328
     329
     330ssize_t cfa_read(int fd, void *buf, size_t count) {
     331        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READ)
     332                return read( fd, buf, count );
     333        #else
     334                __submit_prelude
     335
     336                (*sqe){ IORING_OP_READ, fd, buf, count, 0 };
     337
     338                __submit_wait
     339        #endif
     340}
     341
     342ssize_t cfa_write(int fd, void *buf, size_t count) {
     343        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_WRITE)
     344                return read( fd, buf, count );
     345        #else
     346                __submit_prelude
     347
     348                (*sqe){ IORING_OP_WRITE, fd, buf, count, 0 };
     349
     350                __submit_wait
     351        #endif
     352}
     353
     354//-----------------------------------------------------------------------------
     355// Check if a function is asynchronous
     356
     357// Macro magic to reduce the size of the following switch case
     358#define IS_DEFINED_APPLY(f, ...) f(__VA_ARGS__)
     359#define IS_DEFINED_SECOND(first, second, ...) second
     360#define IS_DEFINED_TEST(expansion) _CFA_IO_FEATURE_##expansion
     361#define IS_DEFINED(macro) IS_DEFINED_APPLY( IS_DEFINED_SECOND,IS_DEFINED_TEST(macro) false, true)
     362
     363bool has_user_level_blocking( fptr_t func ) {
     364        #if defined(HAVE_LINUX_IO_URING_H)
     365                #if defined(HAVE_PREADV2)
     366                        if( /*func == (fptr_t)preadv2 || */
     367                                func == (fptr_t)cfa_preadv2 )
     368                                #define _CFA_IO_FEATURE_IORING_OP_READV ,
     369                                return IS_DEFINED(IORING_OP_READV);
    151370                #endif
    152         }
    153 
    154         ssize_t cfa_recvmsg(int sockfd, struct msghdr *msg, int flags) {
    155                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_RECVMSG)
    156                         return recvmsg(sockfd, msg, flags);
    157                 #else
    158                         __submit_prelude
    159 
    160                         (*sqe){ IORING_OP_RECVMSG, sockfd, msg, 1, 0 };
    161                         sqe->msg_flags = flags;
    162 
    163                         __submit_wait
     371
     372                #if defined(HAVE_PWRITEV2)
     373                        if( /*func == (fptr_t)pwritev2 || */
     374                                func == (fptr_t)cfa_pwritev2 )
     375                                #define _CFA_IO_FEATURE_IORING_OP_WRITEV ,
     376                                return IS_DEFINED(IORING_OP_WRITEV);
    164377                #endif
    165         }
    166 
    167         ssize_t cfa_send(int sockfd, const void *buf, size_t len, int flags) {
    168                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SEND)
    169                         return send( sockfd, buf, len, flags );
    170                 #else
    171                         __submit_prelude
    172 
    173                         (*sqe){ IORING_OP_SEND, sockfd };
    174                         sqe->addr = (uint64_t)buf;
    175                         sqe->len = len;
    176                         sqe->msg_flags = flags;
    177 
    178                         __submit_wait
    179                 #endif
    180         }
    181 
    182         ssize_t cfa_recv(int sockfd, void *buf, size_t len, int flags) {
    183                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_RECV)
    184                         return recv( sockfd, buf, len, flags );
    185                 #else
    186                         __submit_prelude
    187 
    188                         (*sqe){ IORING_OP_RECV, sockfd };
    189                         sqe->addr = (uint64_t)buf;
    190                         sqe->len = len;
    191                         sqe->msg_flags = flags;
    192 
    193                         __submit_wait
    194                 #endif
    195         }
    196 
    197         int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
    198                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_ACCEPT)
    199                         return accept4( sockfd, addr, addrlen, flags );
    200                 #else
    201                         __submit_prelude
    202 
    203                         (*sqe){ IORING_OP_ACCEPT, sockfd };
    204                         sqe->addr = addr;
    205                         sqe->addr2 = addrlen;
    206                         sqe->accept_flags = flags;
    207 
    208                         __submit_wait
    209                 #endif
    210         }
    211 
    212         int cfa_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
    213                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_CONNECT)
    214                         return connect( sockfd, addr, addrlen );
    215                 #else
    216                         __submit_prelude
    217 
    218                         (*sqe){ IORING_OP_CONNECT, sockfd };
    219                         sqe->addr = (uint64_t)addr;
    220                         sqe->off = addrlen;
    221 
    222                         __submit_wait
    223                 #endif
    224         }
    225 
    226         int cfa_fallocate(int fd, int mode, uint64_t offset, uint64_t len) {
    227                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FALLOCATE)
    228                         return fallocate( fd, mode, offset, len );
    229                 #else
    230                         __submit_prelude
    231 
    232                         (*sqe){ IORING_OP_FALLOCATE, fd };
    233                         sqe->off = offset;
    234                         sqe->len = length;
    235                         sqe->mode = mode;
    236 
    237                         __submit_wait
    238                 #endif
    239         }
    240 
    241         int cfa_fadvise(int fd, uint64_t offset, uint64_t len, int advice) {
    242                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FADVISE)
    243                         return posix_fadvise( fd, offset, len, advice );
    244                 #else
    245                         __submit_prelude
    246 
    247                         (*sqe){ IORING_OP_FADVISE, fd };
    248                         sqe->off = (uint64_t)offset;
    249                         sqe->len = length;
    250                         sqe->fadvise_advice = advice;
    251 
    252                         __submit_wait
    253                 #endif
    254         }
    255 
    256         int cfa_madvise(void *addr, size_t length, int advice) {
    257                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_MADVISE)
    258                         return madvise( addr, length, advice );
    259                 #else
    260                         __submit_prelude
    261 
    262                         (*sqe){ IORING_OP_MADVISE, 0 };
    263                         sqe->addr = (uint64_t)addr;
    264                         sqe->len = length;
    265                         sqe->fadvise_advice = advice;
    266 
    267                         __submit_wait
    268                 #endif
    269         }
    270 
    271         int cfa_openat(int dirfd, const char *pathname, int flags, mode_t mode) {
    272                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_OPENAT)
    273                         return openat( dirfd, pathname, flags, mode );
    274                 #else
    275                         __submit_prelude
    276 
    277                         (*sqe){ IORING_OP_OPENAT, dirfd };
    278                         sqe->addr = (uint64_t)pathname;
    279                         sqe->open_flags = flags;
    280                         sqe->mode = mode;
    281 
    282                         __submit_wait
    283                 #endif
    284         }
    285 
    286         int cfa_close(int fd) {
    287                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_CLOSE)
    288                         return close( fd );
    289                 #else
    290                         __submit_prelude
    291 
    292                         (*sqe){ IORING_OP_CLOSE, fd };
    293 
    294                         __submit_wait
    295                 #endif
    296         }
    297 
    298 
    299         ssize_t cfa_read(int fd, void *buf, size_t count) {
    300                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READ)
    301                         return read( fd, buf, count );
    302                 #else
    303                         __submit_prelude
    304 
    305                         (*sqe){ IORING_OP_READ, fd, buf, count, 0 };
    306 
    307                         __submit_wait
    308                 #endif
    309         }
    310 
    311         ssize_t cfa_write(int fd, void *buf, size_t count) {
    312                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_WRITE)
    313                         return read( fd, buf, count );
    314                 #else
    315                         __submit_prelude
    316 
    317                         (*sqe){ IORING_OP_WRITE, fd, buf, count, 0 };
    318 
    319                         __submit_wait
    320                 #endif
    321         }
    322 
    323         //-----------------------------------------------------------------------------
    324         // Check if a function is asynchronous
    325 
    326         // Macro magic to reduce the size of the following switch case
    327         #define IS_DEFINED_APPLY(f, ...) f(__VA_ARGS__)
    328         #define IS_DEFINED_SECOND(first, second, ...) second
    329         #define IS_DEFINED_TEST(expansion) _CFA_IO_FEATURE_##expansion
    330         #define IS_DEFINED(macro) IS_DEFINED_APPLY( IS_DEFINED_SECOND,IS_DEFINED_TEST(macro) false, true)
    331 
    332         bool has_user_level_blocking( fptr_t func ) {
    333                 #if defined(HAVE_LINUX_IO_URING_H)
    334                         #if defined(HAVE_PREADV2)
    335                                 if( /*func == (fptr_t)preadv2 || */
    336                                         func == (fptr_t)cfa_preadv2 )
    337                                         #define _CFA_IO_FEATURE_IORING_OP_READV ,
    338                                         return IS_DEFINED(IORING_OP_READV);
    339                         #endif
    340 
    341                         #if defined(HAVE_PWRITEV2)
    342                                 if( /*func == (fptr_t)pwritev2 || */
    343                                         func == (fptr_t)cfa_pwritev2 )
    344                                         #define _CFA_IO_FEATURE_IORING_OP_WRITEV ,
    345                                         return IS_DEFINED(IORING_OP_WRITEV);
    346                         #endif
    347 
    348                         if( /*func == (fptr_t)fsync || */
    349                                 func == (fptr_t)cfa_fsync )
    350                                 #define _CFA_IO_FEATURE_IORING_OP_FSYNC ,
    351                                 return IS_DEFINED(IORING_OP_FSYNC);
    352 
    353                         if( /*func == (fptr_t)ync_file_range || */
    354                                 func == (fptr_t)cfa_sync_file_range )
    355                                 #define _CFA_IO_FEATURE_IORING_OP_SYNC_FILE_RANGE ,
    356                                 return IS_DEFINED(IORING_OP_SYNC_FILE_RANGE);
    357 
    358                         if( /*func == (fptr_t)sendmsg || */
    359                                 func == (fptr_t)cfa_sendmsg )
    360                                 #define _CFA_IO_FEATURE_IORING_OP_SENDMSG ,
    361                                 return IS_DEFINED(IORING_OP_SENDMSG);
    362 
    363                         if( /*func == (fptr_t)recvmsg || */
    364                                 func == (fptr_t)cfa_recvmsg )
    365                                 #define _CFA_IO_FEATURE_IORING_OP_RECVMSG ,
    366                                 return IS_DEFINED(IORING_OP_RECVMSG);
    367 
    368                         if( /*func == (fptr_t)send || */
    369                                 func == (fptr_t)cfa_send )
    370                                 #define _CFA_IO_FEATURE_IORING_OP_SEND ,
    371                                 return IS_DEFINED(IORING_OP_SEND);
    372 
    373                         if( /*func == (fptr_t)recv || */
    374                                 func == (fptr_t)cfa_recv )
    375                                 #define _CFA_IO_FEATURE_IORING_OP_RECV ,
    376                                 return IS_DEFINED(IORING_OP_RECV);
    377 
    378                         if( /*func == (fptr_t)accept4 || */
    379                                 func == (fptr_t)cfa_accept4 )
    380                                 #define _CFA_IO_FEATURE_IORING_OP_ACCEPT ,
    381                                 return IS_DEFINED(IORING_OP_ACCEPT);
    382 
    383                         if( /*func == (fptr_t)connect || */
    384                                 func == (fptr_t)cfa_connect )
    385                                 #define _CFA_IO_FEATURE_IORING_OP_CONNECT ,
    386                                 return IS_DEFINED(IORING_OP_CONNECT);
    387 
    388                         if( /*func == (fptr_t)fallocate || */
    389                                 func == (fptr_t)cfa_fallocate )
    390                                 #define _CFA_IO_FEATURE_IORING_OP_FALLOCATE ,
    391                                 return IS_DEFINED(IORING_OP_FALLOCATE);
    392 
    393                         if( /*func == (fptr_t)posix_fadvise || */
    394                                 func == (fptr_t)cfa_fadvise )
    395                                 #define _CFA_IO_FEATURE_IORING_OP_FADVISE ,
    396                                 return IS_DEFINED(IORING_OP_FADVISE);
    397 
    398                         if( /*func == (fptr_t)madvise || */
    399                                 func == (fptr_t)cfa_madvise )
    400                                 #define _CFA_IO_FEATURE_IORING_OP_MADVISE ,
    401                                 return IS_DEFINED(IORING_OP_MADVISE);
    402 
    403                         if( /*func == (fptr_t)openat || */
    404                                 func == (fptr_t)cfa_openat )
    405                                 #define _CFA_IO_FEATURE_IORING_OP_OPENAT ,
    406                                 return IS_DEFINED(IORING_OP_OPENAT);
    407 
    408                         if( /*func == (fptr_t)close || */
    409                                 func == (fptr_t)cfa_close )
    410                                 #define _CFA_IO_FEATURE_IORING_OP_CLOSE ,
    411                                 return IS_DEFINED(IORING_OP_CLOSE);
    412 
    413                         if( /*func == (fptr_t)read || */
    414                                 func == (fptr_t)cfa_read )
    415                                 #define _CFA_IO_FEATURE_IORING_OP_READ ,
    416                                 return IS_DEFINED(IORING_OP_READ);
    417 
    418                         if( /*func == (fptr_t)write || */
    419                                 func == (fptr_t)cfa_write )
    420                                 #define _CFA_IO_FEATURE_IORING_OP_WRITE ,
    421                                 return IS_DEFINED(IORING_OP_WRITE);
    422                 #endif
    423 
    424                 return false;
    425         }
    426 #endif
     378
     379                if( /*func == (fptr_t)fsync || */
     380                        func == (fptr_t)cfa_fsync )
     381                        #define _CFA_IO_FEATURE_IORING_OP_FSYNC ,
     382                        return IS_DEFINED(IORING_OP_FSYNC);
     383
     384                if( /*func == (fptr_t)ync_file_range || */
     385                        func == (fptr_t)cfa_sync_file_range )
     386                        #define _CFA_IO_FEATURE_IORING_OP_SYNC_FILE_RANGE ,
     387                        return IS_DEFINED(IORING_OP_SYNC_FILE_RANGE);
     388
     389                if( /*func == (fptr_t)sendmsg || */
     390                        func == (fptr_t)cfa_sendmsg )
     391                        #define _CFA_IO_FEATURE_IORING_OP_SENDMSG ,
     392                        return IS_DEFINED(IORING_OP_SENDMSG);
     393
     394                if( /*func == (fptr_t)recvmsg || */
     395                        func == (fptr_t)cfa_recvmsg )
     396                        #define _CFA_IO_FEATURE_IORING_OP_RECVMSG ,
     397                        return IS_DEFINED(IORING_OP_RECVMSG);
     398
     399                if( /*func == (fptr_t)send || */
     400                        func == (fptr_t)cfa_send )
     401                        #define _CFA_IO_FEATURE_IORING_OP_SEND ,
     402                        return IS_DEFINED(IORING_OP_SEND);
     403
     404                if( /*func == (fptr_t)recv || */
     405                        func == (fptr_t)cfa_recv )
     406                        #define _CFA_IO_FEATURE_IORING_OP_RECV ,
     407                        return IS_DEFINED(IORING_OP_RECV);
     408
     409                if( /*func == (fptr_t)accept4 || */
     410                        func == (fptr_t)cfa_accept4 )
     411                        #define _CFA_IO_FEATURE_IORING_OP_ACCEPT ,
     412                        return IS_DEFINED(IORING_OP_ACCEPT);
     413
     414                if( /*func == (fptr_t)connect || */
     415                        func == (fptr_t)cfa_connect )
     416                        #define _CFA_IO_FEATURE_IORING_OP_CONNECT ,
     417                        return IS_DEFINED(IORING_OP_CONNECT);
     418
     419                if( /*func == (fptr_t)fallocate || */
     420                        func == (fptr_t)cfa_fallocate )
     421                        #define _CFA_IO_FEATURE_IORING_OP_FALLOCATE ,
     422                        return IS_DEFINED(IORING_OP_FALLOCATE);
     423
     424                if( /*func == (fptr_t)posix_fadvise || */
     425                        func == (fptr_t)cfa_fadvise )
     426                        #define _CFA_IO_FEATURE_IORING_OP_FADVISE ,
     427                        return IS_DEFINED(IORING_OP_FADVISE);
     428
     429                if( /*func == (fptr_t)madvise || */
     430                        func == (fptr_t)cfa_madvise )
     431                        #define _CFA_IO_FEATURE_IORING_OP_MADVISE ,
     432                        return IS_DEFINED(IORING_OP_MADVISE);
     433
     434                if( /*func == (fptr_t)openat || */
     435                        func == (fptr_t)cfa_openat )
     436                        #define _CFA_IO_FEATURE_IORING_OP_OPENAT ,
     437                        return IS_DEFINED(IORING_OP_OPENAT);
     438
     439                if( /*func == (fptr_t)close || */
     440                        func == (fptr_t)cfa_close )
     441                        #define _CFA_IO_FEATURE_IORING_OP_CLOSE ,
     442                        return IS_DEFINED(IORING_OP_CLOSE);
     443
     444                if( /*func == (fptr_t)read || */
     445                        func == (fptr_t)cfa_read )
     446                        #define _CFA_IO_FEATURE_IORING_OP_READ ,
     447                        return IS_DEFINED(IORING_OP_READ);
     448
     449                if( /*func == (fptr_t)write || */
     450                        func == (fptr_t)cfa_write )
     451                        #define _CFA_IO_FEATURE_IORING_OP_WRITE ,
     452                        return IS_DEFINED(IORING_OP_WRITE);
     453        #endif
     454
     455        return false;
     456}
Note: See TracChangeset for help on using the changeset viewer.