Ignore:
Timestamp:
Jul 1, 2020, 3:15:24 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:
4b84e35
Parents:
df40a56 (diff), 31bb2e1 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src/concurrency
Files:
1 added
2 edited

Legend:

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

    rdf40a56 r4ec028d  
    3838
    3939#else
     40        #define _GNU_SOURCE         /* See feature_test_macros(7) */
     41        #include <errno.h>
     42        #include <stdint.h>
     43        #include <string.h>
     44        #include <unistd.h>
     45        #include <sys/mman.h>
     46
    4047        extern "C" {
    41                 #define _GNU_SOURCE         /* See feature_test_macros(7) */
    42                 #include <errno.h>
    43                 #include <stdint.h>
    44                 #include <string.h>
    45                 #include <unistd.h>
    46                 #include <sys/mman.h>
    4748                #include <sys/syscall.h>
    4849
     
    420421// I/O Polling
    421422//=============================================================================================
    422         struct io_user_data {
    423                 int32_t result;
    424                 $thread * thrd;
    425         };
    426 
    427423        // Process a single completion message from the io_uring
    428424        // This is NOT thread-safe
     
    505501                        /* paranoid */ verify(&cqe);
    506502
    507                         struct io_user_data * data = (struct io_user_data *)(uintptr_t)cqe.user_data;
     503                        struct __io_user_data_t * data = (struct __io_user_data_t *)(uintptr_t)cqe.user_data;
    508504                        __cfadbg_print_safe( io, "Kernel I/O : Performed reading io cqe %p, result %d for %p\n", data, cqe.res, data->thrd );
    509505
     
    685681//
    686682
    687         // [* struct io_uring_sqe, uint32_t] __submit_alloc( struct __io_data & ring, uint64_t data ) __attribute__((noinline));
    688         static inline [* struct io_uring_sqe, uint32_t] __submit_alloc( struct __io_data & ring, uint64_t data ) {
     683        [* struct io_uring_sqe, uint32_t] __submit_alloc( struct __io_data & ring, uint64_t data ) {
    689684                verify( data != 0 );
    690685
     
    777772        }
    778773
    779         // void __submit( struct __io_data & ring, uint32_t idx ) __attribute__((noinline));
    780         static inline void __submit( struct __io_data & ring, uint32_t idx ) {
     774        void __submit( struct __io_data & ring, uint32_t idx ) {
    781775                // Get now the data we definetely need
    782776                uint32_t * const tail = ring.submit_q.tail;
     
    826820                }
    827821        }
    828 
    829         static inline void ?{}(struct io_uring_sqe & this, uint8_t opcode, int fd) {
    830                 this.opcode = opcode;
    831                 #if !defined(IOSQE_ASYNC)
    832                         this.flags = 0;
    833                 #else
    834                         this.flags = IOSQE_ASYNC;
    835                 #endif
    836                 this.ioprio = 0;
    837                 this.fd = fd;
    838                 this.off = 0;
    839                 this.addr = 0;
    840                 this.len = 0;
    841                 this.rw_flags = 0;
    842                 this.__pad2[0] = this.__pad2[1] = this.__pad2[2] = 0;
    843         }
    844 
    845         static inline void ?{}(struct io_uring_sqe & this, uint8_t opcode, int fd, void * addr, uint32_t len, uint64_t off ) {
    846                 (this){ opcode, fd };
    847                 this.off = off;
    848                 this.addr = (uint64_t)(uintptr_t)addr;
    849                 this.len = len;
    850         }
    851 
    852 
    853 //=============================================================================================
    854 // I/O Interface
    855 //=============================================================================================
    856 
    857         #define __submit_prelude \
    858                 io_user_data data = { 0, active_thread() }; \
    859                 struct __io_data & ring = *data.thrd->curr_cluster->io; \
    860                 struct io_uring_sqe * sqe; \
    861                 uint32_t idx; \
    862                 [sqe, idx] = __submit_alloc( ring, (uint64_t)(uintptr_t)&data );
    863 
    864         #define __submit_wait \
    865                 /*__cfaabi_bits_print_safe( STDERR_FILENO, "Preparing user data %p for %p\n", &data, data.thrd );*/ \
    866                 verify( sqe->user_data == (uint64_t)(uintptr_t)&data ); \
    867                 __submit( ring, idx ); \
    868                 park( __cfaabi_dbg_ctx ); \
    869                 return data.result;
    870822#endif
    871 
    872 // Some forward declarations
    873 extern "C" {
    874         #include <unistd.h>
    875         #include <sys/types.h>
    876         #include <sys/socket.h>
    877         #include <sys/syscall.h>
    878 
    879 #if defined(HAVE_PREADV2)
    880         struct iovec;
    881         extern ssize_t preadv2 (int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
    882 #endif
    883 #if defined(HAVE_PWRITEV2)
    884         struct iovec;
    885         extern ssize_t pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
    886 #endif
    887 
    888         extern int fsync(int fd);
    889         extern int sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags);
    890 
    891         struct msghdr;
    892         struct sockaddr;
    893         extern ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
    894         extern ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
    895         extern ssize_t send(int sockfd, const void *buf, size_t len, int flags);
    896         extern ssize_t recv(int sockfd, void *buf, size_t len, int flags);
    897         extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
    898         extern int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
    899 
    900         extern int fallocate(int fd, int mode, uint64_t offset, uint64_t len);
    901         extern int posix_fadvise(int fd, uint64_t offset, uint64_t len, int advice);
    902         extern int madvise(void *addr, size_t length, int advice);
    903 
    904         extern int openat(int dirfd, const char *pathname, int flags, mode_t mode);
    905         extern int close(int fd);
    906 
    907         extern ssize_t read (int fd, void *buf, size_t count);
    908 }
    909 
    910 //-----------------------------------------------------------------------------
    911 // Asynchronous operations
    912 #if defined(HAVE_PREADV2)
    913         ssize_t cfa_preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) {
    914                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READV)
    915                         return preadv2(fd, iov, iovcnt, offset, flags);
    916                 #else
    917                         __submit_prelude
    918 
    919                         (*sqe){ IORING_OP_READV, fd, iov, iovcnt, offset };
    920 
    921                         __submit_wait
    922                 #endif
    923         }
    924 #endif
    925 
    926 #if defined(HAVE_PWRITEV2)
    927         ssize_t cfa_pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) {
    928                 #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_WRITEV)
    929                         return pwritev2(fd, iov, iovcnt, offset, flags);
    930                 #else
    931                         __submit_prelude
    932 
    933                         (*sqe){ IORING_OP_WRITEV, fd, iov, iovcnt, offset };
    934 
    935                         __submit_wait
    936                 #endif
    937         }
    938 #endif
    939 
    940 int cfa_fsync(int fd) {
    941         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FSYNC)
    942                 return fsync(fd);
    943         #else
    944                 __submit_prelude
    945 
    946                 (*sqe){ IORING_OP_FSYNC, fd };
    947 
    948                 __submit_wait
    949         #endif
    950 }
    951 
    952 int cfa_sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags) {
    953         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SYNC_FILE_RANGE)
    954                 return sync_file_range(fd, offset, nbytes, flags);
    955         #else
    956                 __submit_prelude
    957 
    958                 (*sqe){ IORING_OP_SYNC_FILE_RANGE, fd };
    959                 sqe->off = offset;
    960                 sqe->len = nbytes;
    961                 sqe->sync_range_flags = flags;
    962 
    963                 __submit_wait
    964         #endif
    965 }
    966 
    967 
    968 ssize_t cfa_sendmsg(int sockfd, const struct msghdr *msg, int flags) {
    969         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SENDMSG)
    970                 return sendmsg(sockfd, msg, flags);
    971         #else
    972                 __submit_prelude
    973 
    974                 (*sqe){ IORING_OP_SENDMSG, sockfd, msg, 1, 0 };
    975                 sqe->msg_flags = flags;
    976 
    977                 __submit_wait
    978         #endif
    979 }
    980 
    981 ssize_t cfa_recvmsg(int sockfd, struct msghdr *msg, int flags) {
    982         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_RECVMSG)
    983                 return recvmsg(sockfd, msg, flags);
    984         #else
    985                 __submit_prelude
    986 
    987                 (*sqe){ IORING_OP_RECVMSG, sockfd, msg, 1, 0 };
    988                 sqe->msg_flags = flags;
    989 
    990                 __submit_wait
    991         #endif
    992 }
    993 
    994 ssize_t cfa_send(int sockfd, const void *buf, size_t len, int flags) {
    995         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SEND)
    996                 return send( sockfd, buf, len, flags );
    997         #else
    998                 __submit_prelude
    999 
    1000                 (*sqe){ IORING_OP_SEND, sockfd };
    1001                 sqe->addr = (uint64_t)buf;
    1002                 sqe->len = len;
    1003                 sqe->msg_flags = flags;
    1004 
    1005                 __submit_wait
    1006         #endif
    1007 }
    1008 
    1009 ssize_t cfa_recv(int sockfd, void *buf, size_t len, int flags) {
    1010         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_RECV)
    1011                 return recv( sockfd, buf, len, flags );
    1012         #else
    1013                 __submit_prelude
    1014 
    1015                 (*sqe){ IORING_OP_RECV, sockfd };
    1016                 sqe->addr = (uint64_t)buf;
    1017                 sqe->len = len;
    1018                 sqe->msg_flags = flags;
    1019 
    1020                 __submit_wait
    1021         #endif
    1022 }
    1023 
    1024 int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
    1025         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_ACCEPT)
    1026                 return accept4( sockfd, addr, addrlen, flags );
    1027         #else
    1028                 __submit_prelude
    1029 
    1030                 (*sqe){ IORING_OP_ACCEPT, sockfd };
    1031                 sqe->addr = addr;
    1032                 sqe->addr2 = addrlen;
    1033                 sqe->accept_flags = flags;
    1034 
    1035                 __submit_wait
    1036         #endif
    1037 }
    1038 
    1039 int cfa_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
    1040         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_CONNECT)
    1041                 return connect( sockfd, addr, addrlen );
    1042         #else
    1043                 __submit_prelude
    1044 
    1045                 (*sqe){ IORING_OP_CONNECT, sockfd };
    1046                 sqe->addr = (uint64_t)addr;
    1047                 sqe->off = addrlen;
    1048 
    1049                 __submit_wait
    1050         #endif
    1051 }
    1052 
    1053 int cfa_fallocate(int fd, int mode, uint64_t offset, uint64_t len) {
    1054         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FALLOCATE)
    1055                 return fallocate( fd, mode, offset, len );
    1056         #else
    1057                 __submit_prelude
    1058 
    1059                 (*sqe){ IORING_OP_FALLOCATE, fd };
    1060                 sqe->off = offset;
    1061                 sqe->len = length;
    1062                 sqe->mode = mode;
    1063 
    1064                 __submit_wait
    1065         #endif
    1066 }
    1067 
    1068 int cfa_fadvise(int fd, uint64_t offset, uint64_t len, int advice) {
    1069         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FADVISE)
    1070                 return posix_fadvise( fd, offset, len, advice );
    1071         #else
    1072                 __submit_prelude
    1073 
    1074                 (*sqe){ IORING_OP_FADVISE, fd };
    1075                 sqe->off = (uint64_t)offset;
    1076                 sqe->len = length;
    1077                 sqe->fadvise_advice = advice;
    1078 
    1079                 __submit_wait
    1080         #endif
    1081 }
    1082 
    1083 int cfa_madvise(void *addr, size_t length, int advice) {
    1084         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_MADVISE)
    1085                 return madvise( addr, length, advice );
    1086         #else
    1087                 __submit_prelude
    1088 
    1089                 (*sqe){ IORING_OP_MADVISE, 0 };
    1090                 sqe->addr = (uint64_t)addr;
    1091                 sqe->len = length;
    1092                 sqe->fadvise_advice = advice;
    1093 
    1094                 __submit_wait
    1095         #endif
    1096 }
    1097 
    1098 int cfa_openat(int dirfd, const char *pathname, int flags, mode_t mode) {
    1099         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_OPENAT)
    1100                 return openat( dirfd, pathname, flags, mode );
    1101         #else
    1102                 __submit_prelude
    1103 
    1104                 (*sqe){ IORING_OP_OPENAT, dirfd };
    1105                 sqe->addr = (uint64_t)pathname;
    1106                 sqe->open_flags = flags;
    1107                 sqe->mode = mode;
    1108 
    1109                 __submit_wait
    1110         #endif
    1111 }
    1112 
    1113 int cfa_close(int fd) {
    1114         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_CLOSE)
    1115                 return close( fd );
    1116         #else
    1117                 __submit_prelude
    1118 
    1119                 (*sqe){ IORING_OP_CLOSE, fd };
    1120 
    1121                 __submit_wait
    1122         #endif
    1123 }
    1124 
    1125 
    1126 ssize_t cfa_read(int fd, void *buf, size_t count) {
    1127         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READ)
    1128                 return read( fd, buf, count );
    1129         #else
    1130                 __submit_prelude
    1131 
    1132                 (*sqe){ IORING_OP_READ, fd, buf, count, 0 };
    1133 
    1134                 __submit_wait
    1135         #endif
    1136 }
    1137 
    1138 ssize_t cfa_write(int fd, void *buf, size_t count) {
    1139         #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_WRITE)
    1140                 return read( fd, buf, count );
    1141         #else
    1142                 __submit_prelude
    1143 
    1144                 (*sqe){ IORING_OP_WRITE, fd, buf, count, 0 };
    1145 
    1146                 __submit_wait
    1147         #endif
    1148 }
    1149 
    1150 //-----------------------------------------------------------------------------
    1151 // Check if a function is asynchronous
    1152 
    1153 // Macro magic to reduce the size of the following switch case
    1154 #define IS_DEFINED_APPLY(f, ...) f(__VA_ARGS__)
    1155 #define IS_DEFINED_SECOND(first, second, ...) second
    1156 #define IS_DEFINED_TEST(expansion) _CFA_IO_FEATURE_##expansion
    1157 #define IS_DEFINED(macro) IS_DEFINED_APPLY( IS_DEFINED_SECOND,IS_DEFINED_TEST(macro) false, true)
    1158 
    1159 bool has_user_level_blocking( fptr_t func ) {
    1160         #if defined(HAVE_LINUX_IO_URING_H)
    1161                 #if defined(HAVE_PREADV2)
    1162                         if( /*func == (fptr_t)preadv2 || */
    1163                                 func == (fptr_t)cfa_preadv2 )
    1164                                 #define _CFA_IO_FEATURE_IORING_OP_READV ,
    1165                                 return IS_DEFINED(IORING_OP_READV);
    1166                 #endif
    1167 
    1168                 #if defined(HAVE_PWRITEV2)
    1169                         if( /*func == (fptr_t)pwritev2 || */
    1170                                 func == (fptr_t)cfa_pwritev2 )
    1171                                 #define _CFA_IO_FEATURE_IORING_OP_WRITEV ,
    1172                                 return IS_DEFINED(IORING_OP_WRITEV);
    1173                 #endif
    1174 
    1175                 if( /*func == (fptr_t)fsync || */
    1176                         func == (fptr_t)cfa_fsync )
    1177                         #define _CFA_IO_FEATURE_IORING_OP_FSYNC ,
    1178                         return IS_DEFINED(IORING_OP_FSYNC);
    1179 
    1180                 if( /*func == (fptr_t)ync_file_range || */
    1181                         func == (fptr_t)cfa_sync_file_range )
    1182                         #define _CFA_IO_FEATURE_IORING_OP_SYNC_FILE_RANGE ,
    1183                         return IS_DEFINED(IORING_OP_SYNC_FILE_RANGE);
    1184 
    1185                 if( /*func == (fptr_t)sendmsg || */
    1186                         func == (fptr_t)cfa_sendmsg )
    1187                         #define _CFA_IO_FEATURE_IORING_OP_SENDMSG ,
    1188                         return IS_DEFINED(IORING_OP_SENDMSG);
    1189 
    1190                 if( /*func == (fptr_t)recvmsg || */
    1191                         func == (fptr_t)cfa_recvmsg )
    1192                         #define _CFA_IO_FEATURE_IORING_OP_RECVMSG ,
    1193                         return IS_DEFINED(IORING_OP_RECVMSG);
    1194 
    1195                 if( /*func == (fptr_t)send || */
    1196                         func == (fptr_t)cfa_send )
    1197                         #define _CFA_IO_FEATURE_IORING_OP_SEND ,
    1198                         return IS_DEFINED(IORING_OP_SEND);
    1199 
    1200                 if( /*func == (fptr_t)recv || */
    1201                         func == (fptr_t)cfa_recv )
    1202                         #define _CFA_IO_FEATURE_IORING_OP_RECV ,
    1203                         return IS_DEFINED(IORING_OP_RECV);
    1204 
    1205                 if( /*func == (fptr_t)accept4 || */
    1206                         func == (fptr_t)cfa_accept4 )
    1207                         #define _CFA_IO_FEATURE_IORING_OP_ACCEPT ,
    1208                         return IS_DEFINED(IORING_OP_ACCEPT);
    1209 
    1210                 if( /*func == (fptr_t)connect || */
    1211                         func == (fptr_t)cfa_connect )
    1212                         #define _CFA_IO_FEATURE_IORING_OP_CONNECT ,
    1213                         return IS_DEFINED(IORING_OP_CONNECT);
    1214 
    1215                 if( /*func == (fptr_t)fallocate || */
    1216                         func == (fptr_t)cfa_fallocate )
    1217                         #define _CFA_IO_FEATURE_IORING_OP_FALLOCATE ,
    1218                         return IS_DEFINED(IORING_OP_FALLOCATE);
    1219 
    1220                 if( /*func == (fptr_t)posix_fadvise || */
    1221                         func == (fptr_t)cfa_fadvise )
    1222                         #define _CFA_IO_FEATURE_IORING_OP_FADVISE ,
    1223                         return IS_DEFINED(IORING_OP_FADVISE);
    1224 
    1225                 if( /*func == (fptr_t)madvise || */
    1226                         func == (fptr_t)cfa_madvise )
    1227                         #define _CFA_IO_FEATURE_IORING_OP_MADVISE ,
    1228                         return IS_DEFINED(IORING_OP_MADVISE);
    1229 
    1230                 if( /*func == (fptr_t)openat || */
    1231                         func == (fptr_t)cfa_openat )
    1232                         #define _CFA_IO_FEATURE_IORING_OP_OPENAT ,
    1233                         return IS_DEFINED(IORING_OP_OPENAT);
    1234 
    1235                 if( /*func == (fptr_t)close || */
    1236                         func == (fptr_t)cfa_close )
    1237                         #define _CFA_IO_FEATURE_IORING_OP_CLOSE ,
    1238                         return IS_DEFINED(IORING_OP_CLOSE);
    1239 
    1240                 if( /*func == (fptr_t)read || */
    1241                         func == (fptr_t)cfa_read )
    1242                         #define _CFA_IO_FEATURE_IORING_OP_READ ,
    1243                         return IS_DEFINED(IORING_OP_READ);
    1244 
    1245                 if( /*func == (fptr_t)write || */
    1246                         func == (fptr_t)cfa_write )
    1247                         #define _CFA_IO_FEATURE_IORING_OP_WRITE ,
    1248                         return IS_DEFINED(IORING_OP_WRITE);
    1249         #endif
    1250 
    1251         return false;
    1252 }
  • libcfa/src/concurrency/kernel_private.hfa

    rdf40a56 r4ec028d  
    277277
    278278//-----------------------------------------------------------------------
     279// IO user data
     280struct __io_user_data_t {
     281        int32_t result;
     282        $thread * thrd;
     283};
     284
     285//-----------------------------------------------------------------------
    279286// Statics call at the end of each thread to register statistics
    280287#if !defined(__CFA_NO_STATISTICS__)
Note: See TracChangeset for help on using the changeset viewer.