uringmachine 0.16 → 0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.gitmodules +4 -0
- data/CHANGELOG.md +8 -0
- data/TODO.md +12 -3
- data/examples/bm_send.rb +86 -0
- data/ext/um/um.c +28 -1
- data/ext/um/um.h +3 -0
- data/ext/um/um_class.c +17 -0
- data/ext/um/um_utils.c +38 -15
- data/lib/uringmachine/version.rb +1 -1
- data/test/test_um.rb +76 -0
- data/vendor/libressl/.github/scripts/changelog.sh +74 -0
- data/vendor/libressl/.github/workflows/android.yml +35 -0
- data/vendor/libressl/.github/workflows/cifuzz.yml +33 -0
- data/vendor/libressl/.github/workflows/cmake-config.yml +98 -0
- data/vendor/libressl/.github/workflows/coverity.yml +69 -0
- data/vendor/libressl/.github/workflows/emscripten.yml +71 -0
- data/vendor/libressl/.github/workflows/fedora-rawhide.yml +39 -0
- data/vendor/libressl/.github/workflows/freebsd.yml +71 -0
- data/vendor/libressl/.github/workflows/linux.yml +71 -0
- data/vendor/libressl/.github/workflows/macos.yml +37 -0
- data/vendor/libressl/.github/workflows/release.yml +81 -0
- data/vendor/libressl/.github/workflows/rust-openssl.yml +47 -0
- data/vendor/libressl/.github/workflows/solaris.yml +37 -0
- data/vendor/libressl/.github/workflows/windows.yml +70 -0
- data/vendor/libressl/.gitignore +333 -0
- data/vendor/libressl/CMakeLists.txt +581 -0
- data/vendor/libressl/COPYING +133 -0
- data/vendor/libressl/ChangeLog +3280 -0
- data/vendor/libressl/FindLibreSSL.cmake +232 -0
- data/vendor/libressl/LibreSSLConfig.cmake.in +36 -0
- data/vendor/libressl/Makefile.am +60 -0
- data/vendor/libressl/Makefile.am.common +20 -0
- data/vendor/libressl/OPENBSD_BRANCH +1 -0
- data/vendor/libressl/README.md +238 -0
- data/vendor/libressl/README.mingw.md +43 -0
- data/vendor/libressl/apps/CMakeLists.txt +18 -0
- data/vendor/libressl/apps/Makefile.am +5 -0
- data/vendor/libressl/apps/nc/CMakeLists.txt +67 -0
- data/vendor/libressl/apps/nc/Makefile.am +64 -0
- data/vendor/libressl/apps/nc/compat/accept4.c +17 -0
- data/vendor/libressl/apps/nc/compat/readpassphrase.c +205 -0
- data/vendor/libressl/apps/nc/compat/socket.c +29 -0
- data/vendor/libressl/apps/nc/compat/sys/socket.h +30 -0
- data/vendor/libressl/apps/ocspcheck/CMakeLists.txt +44 -0
- data/vendor/libressl/apps/ocspcheck/Makefile.am +45 -0
- data/vendor/libressl/apps/ocspcheck/compat/.gitignore +0 -0
- data/vendor/libressl/apps/openssl/CMakeLists.txt +97 -0
- data/vendor/libressl/apps/openssl/Makefile.am +108 -0
- data/vendor/libressl/apps/openssl/apps_win.c +138 -0
- data/vendor/libressl/apps/openssl/certhash_win.c +13 -0
- data/vendor/libressl/apps/openssl/compat/clock_gettime_osx.c +26 -0
- data/vendor/libressl/apps/openssl/compat/poll_win.c +329 -0
- data/vendor/libressl/appveyor.yml +53 -0
- data/vendor/libressl/autogen.sh +15 -0
- data/vendor/libressl/check-release.sh +86 -0
- data/vendor/libressl/cmake_export_symbol.cmake +71 -0
- data/vendor/libressl/cmake_uninstall.cmake.in +36 -0
- data/vendor/libressl/config +17 -0
- data/vendor/libressl/configure.ac +165 -0
- data/vendor/libressl/crypto/CMakeLists.txt +863 -0
- data/vendor/libressl/crypto/Makefile.am +962 -0
- data/vendor/libressl/crypto/Makefile.am.arc4random +46 -0
- data/vendor/libressl/crypto/Makefile.am.elf-mips +14 -0
- data/vendor/libressl/crypto/Makefile.am.elf-mips64 +14 -0
- data/vendor/libressl/crypto/Makefile.am.elf-x86_64 +35 -0
- data/vendor/libressl/crypto/Makefile.am.macosx-x86_64 +35 -0
- data/vendor/libressl/crypto/Makefile.am.masm-x86_64 +22 -0
- data/vendor/libressl/crypto/Makefile.am.mingw64-x86_64 +23 -0
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_darwin.c +60 -0
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_linux.c +62 -0
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_none.c +26 -0
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_windows.c +36 -0
- data/vendor/libressl/crypto/arch/loongarch64/crypto_arch.h +21 -0
- data/vendor/libressl/crypto/arch/mips/crypto_arch.h +21 -0
- data/vendor/libressl/crypto/bn/arch/loongarch64/bn_arch.h +23 -0
- data/vendor/libressl/crypto/bn/arch/mips/bn_arch.h +24 -0
- data/vendor/libressl/crypto/compat/.gitignore +31 -0
- data/vendor/libressl/crypto/compat/arc4random.h +41 -0
- data/vendor/libressl/crypto/compat/b_win.c +55 -0
- data/vendor/libressl/crypto/compat/bsd-asprintf.c +96 -0
- data/vendor/libressl/crypto/compat/crypto_lock_win.c +56 -0
- data/vendor/libressl/crypto/compat/explicit_bzero_win.c +13 -0
- data/vendor/libressl/crypto/compat/freezero.c +32 -0
- data/vendor/libressl/crypto/compat/getdelim.c +78 -0
- data/vendor/libressl/crypto/compat/getline.c +40 -0
- data/vendor/libressl/crypto/compat/getopt_long.c +528 -0
- data/vendor/libressl/crypto/compat/getpagesize.c +18 -0
- data/vendor/libressl/crypto/compat/getprogname_linux.c +23 -0
- data/vendor/libressl/crypto/compat/getprogname_unimpl.c +7 -0
- data/vendor/libressl/crypto/compat/getprogname_windows.c +13 -0
- data/vendor/libressl/crypto/compat/posix_win.c +296 -0
- data/vendor/libressl/crypto/compat/syslog_r.c +19 -0
- data/vendor/libressl/crypto/compat/ui_openssl_win.c +334 -0
- data/vendor/libressl/dist.sh +22 -0
- data/vendor/libressl/gen-coverage-report.sh +58 -0
- data/vendor/libressl/gen-openbsd-tags.sh +20 -0
- data/vendor/libressl/include/CMakeLists.txt +61 -0
- data/vendor/libressl/include/Makefile.am +79 -0
- data/vendor/libressl/include/arch/loongarch64/opensslconf.h +150 -0
- data/vendor/libressl/include/arch/mips/opensslconf.h +150 -0
- data/vendor/libressl/include/compat/arpa/inet.h +15 -0
- data/vendor/libressl/include/compat/arpa/nameser.h +25 -0
- data/vendor/libressl/include/compat/cet.h +19 -0
- data/vendor/libressl/include/compat/dirent.h +17 -0
- data/vendor/libressl/include/compat/dirent_msvc.h +611 -0
- data/vendor/libressl/include/compat/endian.h +161 -0
- data/vendor/libressl/include/compat/err.h +95 -0
- data/vendor/libressl/include/compat/fcntl.h +32 -0
- data/vendor/libressl/include/compat/getopt.h +50 -0
- data/vendor/libressl/include/compat/limits.h +25 -0
- data/vendor/libressl/include/compat/netdb.h +10 -0
- data/vendor/libressl/include/compat/netinet/in.h +19 -0
- data/vendor/libressl/include/compat/netinet/ip.h +49 -0
- data/vendor/libressl/include/compat/netinet/tcp.h +10 -0
- data/vendor/libressl/include/compat/poll.h +63 -0
- data/vendor/libressl/include/compat/pthread.h +122 -0
- data/vendor/libressl/include/compat/readpassphrase.h +44 -0
- data/vendor/libressl/include/compat/resolv.h +24 -0
- data/vendor/libressl/include/compat/stdint.h +31 -0
- data/vendor/libressl/include/compat/stdio.h +65 -0
- data/vendor/libressl/include/compat/stdlib.h +57 -0
- data/vendor/libressl/include/compat/string.h +98 -0
- data/vendor/libressl/include/compat/sys/_null.h +18 -0
- data/vendor/libressl/include/compat/sys/ioctl.h +11 -0
- data/vendor/libressl/include/compat/sys/mman.h +19 -0
- data/vendor/libressl/include/compat/sys/param.h +15 -0
- data/vendor/libressl/include/compat/sys/queue.h +536 -0
- data/vendor/libressl/include/compat/sys/select.h +10 -0
- data/vendor/libressl/include/compat/sys/socket.h +18 -0
- data/vendor/libressl/include/compat/sys/stat.h +129 -0
- data/vendor/libressl/include/compat/sys/time.h +37 -0
- data/vendor/libressl/include/compat/sys/tree.h +1006 -0
- data/vendor/libressl/include/compat/sys/types.h +69 -0
- data/vendor/libressl/include/compat/sys/uio.h +17 -0
- data/vendor/libressl/include/compat/syslog.h +38 -0
- data/vendor/libressl/include/compat/time.h +59 -0
- data/vendor/libressl/include/compat/unistd.h +83 -0
- data/vendor/libressl/include/compat/win32netcompat.h +57 -0
- data/vendor/libressl/include/openssl/Makefile.am.tpl +45 -0
- data/vendor/libressl/libcrypto.pc.in +28 -0
- data/vendor/libressl/libressl.pub +2 -0
- data/vendor/libressl/libssl.pc.in +28 -0
- data/vendor/libressl/libtls.pc.in +28 -0
- data/vendor/libressl/m4/ax_add_fortify_source.m4 +80 -0
- data/vendor/libressl/m4/ax_check_compile_flag.m4 +53 -0
- data/vendor/libressl/m4/check-hardening-options.m4 +110 -0
- data/vendor/libressl/m4/check-libc.m4 +189 -0
- data/vendor/libressl/m4/check-os-options.m4 +181 -0
- data/vendor/libressl/m4/disable-compiler-warnings.m4 +44 -0
- data/vendor/libressl/man/CMakeLists.txt +26 -0
- data/vendor/libressl/man/links +2780 -0
- data/vendor/libressl/man/update_links.sh +25 -0
- data/vendor/libressl/openssl.pc.in +11 -0
- data/vendor/libressl/patches/bn_shift.patch +34 -0
- data/vendor/libressl/patches/crypto_arch.h.patch +34 -0
- data/vendor/libressl/patches/crypto_namespace.h.patch +22 -0
- data/vendor/libressl/patches/netcat.c.patch +178 -0
- data/vendor/libressl/patches/openssl.c.patch +12 -0
- data/vendor/libressl/patches/opensslfeatures.h.patch +49 -0
- data/vendor/libressl/patches/patch-amd64-crypto-cpu-caps.c.patch +20 -0
- data/vendor/libressl/patches/patch-i386-crypto-cpu-caps.c.patch +20 -0
- data/vendor/libressl/patches/speed.c.patch +114 -0
- data/vendor/libressl/patches/ssl_namespace.h.patch +21 -0
- data/vendor/libressl/patches/tls.h.patch +16 -0
- data/vendor/libressl/patches/tls_config.c.patch +15 -0
- data/vendor/libressl/patches/win32_amd64_bn_arch.h.patch +28 -0
- data/vendor/libressl/patches/windows_headers.patch +80 -0
- data/vendor/libressl/scripts/config.guess +1774 -0
- data/vendor/libressl/scripts/config.sub +1907 -0
- data/vendor/libressl/scripts/i686-w64-mingw32.cmake +9 -0
- data/vendor/libressl/scripts/test +210 -0
- data/vendor/libressl/scripts/wrap-compiler-for-flag-check +31 -0
- data/vendor/libressl/scripts/x86_64-w64-mingw32.cmake +9 -0
- data/vendor/libressl/ssl/CMakeLists.txt +183 -0
- data/vendor/libressl/ssl/Makefile.am +187 -0
- data/vendor/libressl/tests/CMakeLists.txt +970 -0
- data/vendor/libressl/tests/Makefile.am +944 -0
- data/vendor/libressl/tests/aeadtest.sh +30 -0
- data/vendor/libressl/tests/arc4randomforktest.sh +21 -0
- data/vendor/libressl/tests/asn1time_small.test +10 -0
- data/vendor/libressl/tests/cmake/CMakeLists.txt +52 -0
- data/vendor/libressl/tests/cmake/crypto.c +7 -0
- data/vendor/libressl/tests/cmake/ssl.c +6 -0
- data/vendor/libressl/tests/cmake/tls.c +6 -0
- data/vendor/libressl/tests/compat/pipe2.c +186 -0
- data/vendor/libressl/tests/dtlstest.sh +28 -0
- data/vendor/libressl/tests/evptest.sh +22 -0
- data/vendor/libressl/tests/keypairtest.sh +27 -0
- data/vendor/libressl/tests/mlkem_tests.sh +39 -0
- data/vendor/libressl/tests/ocsptest.bat +25 -0
- data/vendor/libressl/tests/ocsptest.sh +23 -0
- data/vendor/libressl/tests/openssl.cnf +29 -0
- data/vendor/libressl/tests/optionstest.c +381 -0
- data/vendor/libressl/tests/pidwraptest.c +85 -0
- data/vendor/libressl/tests/pidwraptest.sh +26 -0
- data/vendor/libressl/tests/quictest.bat +27 -0
- data/vendor/libressl/tests/quictest.sh +30 -0
- data/vendor/libressl/tests/renegotiation_test.bat +27 -0
- data/vendor/libressl/tests/renegotiation_test.sh +30 -0
- data/vendor/libressl/tests/rfc5280time_small.test +10 -0
- data/vendor/libressl/tests/servertest.bat +27 -0
- data/vendor/libressl/tests/servertest.sh +30 -0
- data/vendor/libressl/tests/shutdowntest.bat +27 -0
- data/vendor/libressl/tests/shutdowntest.sh +30 -0
- data/vendor/libressl/tests/ssltest.bat +32 -0
- data/vendor/libressl/tests/ssltest.sh +48 -0
- data/vendor/libressl/tests/testdsa.bat +47 -0
- data/vendor/libressl/tests/testdsa.sh +57 -0
- data/vendor/libressl/tests/testenc.bat +85 -0
- data/vendor/libressl/tests/testenc.sh +93 -0
- data/vendor/libressl/tests/testrsa.bat +47 -0
- data/vendor/libressl/tests/testrsa.sh +57 -0
- data/vendor/libressl/tests/testssl.bat +171 -0
- data/vendor/libressl/tests/tlstest.bat +27 -0
- data/vendor/libressl/tests/tlstest.sh +28 -0
- data/vendor/libressl/tls/CMakeLists.txt +125 -0
- data/vendor/libressl/tls/Makefile.am +76 -0
- data/vendor/libressl/tls/compat/ftruncate.c +17 -0
- data/vendor/libressl/tls/compat/pread.c +29 -0
- data/vendor/libressl/tls/compat/pwrite.c +29 -0
- data/vendor/libressl/update.sh +460 -0
- data/vendor/liburing/.github/workflows/ci.yml +8 -0
- data/vendor/liburing/configure +23 -2
- data/vendor/liburing/examples/helpers.c +1 -1
- data/vendor/liburing/examples/helpers.h +1 -1
- data/vendor/liburing/examples/reg-wait.c +3 -3
- data/vendor/liburing/examples/zcrx.c +5 -5
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/include/liburing/io_uring.h +16 -0
- data/vendor/liburing/src/include/liburing.h +20 -4
- data/vendor/liburing/src/lib.h +2 -4
- data/vendor/liburing/src/liburing-ffi.map +7 -0
- data/vendor/liburing/src/liburing.map +7 -0
- data/vendor/liburing/src/register.c +5 -0
- data/vendor/liburing/src/sanitize.c +5 -4
- data/vendor/liburing/src/setup.c +43 -28
- data/vendor/liburing/test/Makefile +7 -0
- data/vendor/liburing/test/cmd-discard.c +2 -2
- data/vendor/liburing/test/evfd-short-read.c +84 -0
- data/vendor/liburing/test/fdinfo-sqpoll.c +117 -0
- data/vendor/liburing/test/fdinfo.c +1 -1
- data/vendor/liburing/test/fixed-buf-merge.c +2 -2
- data/vendor/liburing/test/futex-kill.c +135 -0
- data/vendor/liburing/test/helpers.c +1 -1
- data/vendor/liburing/test/helpers.h +1 -1
- data/vendor/liburing/test/init-mem.c +50 -12
- data/vendor/liburing/test/io_uring_passthrough.c +25 -6
- data/vendor/liburing/test/msg-ring.c +123 -9
- data/vendor/liburing/test/recv-bundle-short-ooo.c +16 -1
- data/vendor/liburing/test/recv-inc-ooo.c +411 -0
- data/vendor/liburing/test/recv-mshot-fair.c +513 -0
- data/vendor/liburing/test/reg-wait.c +14 -14
- data/vendor/liburing/test/send-zerocopy.c +4 -4
- data/vendor/liburing/test/timerfd-short-read.c +81 -0
- data/vendor/liburing/test/timestamp.c +382 -0
- data/vendor/liburing/test/zcrx.c +22 -22
- metadata +222 -2
@@ -0,0 +1,513 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Test that fairness exists between multiple streams, and that setting
|
4
|
+
* optlen is honored in terms of terminating a multishot request when
|
5
|
+
* a certain byte limit is reached.
|
6
|
+
*/
|
7
|
+
#include <errno.h>
|
8
|
+
#include <stdio.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <string.h>
|
11
|
+
#include <unistd.h>
|
12
|
+
#include <limits.h>
|
13
|
+
#include <arpa/inet.h>
|
14
|
+
#include <sys/types.h>
|
15
|
+
#include <sys/socket.h>
|
16
|
+
#include <pthread.h>
|
17
|
+
|
18
|
+
#include "liburing.h"
|
19
|
+
#include "helpers.h"
|
20
|
+
|
21
|
+
#define RECV_BIDS 2048
|
22
|
+
#define RECV_BID_MASK (RECV_BIDS - 1)
|
23
|
+
#define RECV_BGID 8
|
24
|
+
#define RECV_BID_SZ 32
|
25
|
+
|
26
|
+
#define PORT 10210
|
27
|
+
#define HOST "127.0.0.1"
|
28
|
+
|
29
|
+
#define NR_RDS 4
|
30
|
+
|
31
|
+
static bool no_limit_support;
|
32
|
+
|
33
|
+
static int use_port = PORT;
|
34
|
+
|
35
|
+
struct recv_data {
|
36
|
+
pthread_barrier_t connect;
|
37
|
+
pthread_barrier_t startup;
|
38
|
+
pthread_barrier_t barrier;
|
39
|
+
|
40
|
+
struct io_uring_buf_ring *br;
|
41
|
+
|
42
|
+
int recv_bytes;
|
43
|
+
int accept_fd;
|
44
|
+
unsigned int max_sends;
|
45
|
+
unsigned int queue_flags;
|
46
|
+
|
47
|
+
int bytes_since_arm;
|
48
|
+
int total_bytes;
|
49
|
+
|
50
|
+
int recv_bundle;
|
51
|
+
|
52
|
+
int use_port;
|
53
|
+
int id;
|
54
|
+
|
55
|
+
int mshot_too_big;
|
56
|
+
int unfair;
|
57
|
+
};
|
58
|
+
|
59
|
+
#define PER_ITER_LIMIT 1024
|
60
|
+
#define PER_MSHOT_LIMIT 4096
|
61
|
+
|
62
|
+
static void arm_recv(struct io_uring *ring, struct recv_data *rd)
|
63
|
+
{
|
64
|
+
struct io_uring_sqe *sqe;
|
65
|
+
int len = PER_ITER_LIMIT;
|
66
|
+
|
67
|
+
if (rd->total_bytes && rd->bytes_since_arm > PER_MSHOT_LIMIT)
|
68
|
+
rd->mshot_too_big++;
|
69
|
+
|
70
|
+
rd->bytes_since_arm = 0;
|
71
|
+
sqe = io_uring_get_sqe(ring);
|
72
|
+
io_uring_prep_recv_multishot(sqe, rd->accept_fd, NULL, len, 0);
|
73
|
+
sqe->optlen = PER_MSHOT_LIMIT;
|
74
|
+
if (rd->recv_bundle)
|
75
|
+
sqe->ioprio |= IORING_RECVSEND_BUNDLE;
|
76
|
+
sqe->buf_group = RECV_BGID;
|
77
|
+
sqe->flags |= IOSQE_BUFFER_SELECT;
|
78
|
+
io_uring_sqe_set_data(sqe, rd);
|
79
|
+
}
|
80
|
+
|
81
|
+
static int recv_prep(struct io_uring *ring, struct recv_data *rd, int *sock)
|
82
|
+
{
|
83
|
+
struct sockaddr_in saddr;
|
84
|
+
int sockfd, ret, val, use_fd;
|
85
|
+
socklen_t socklen;
|
86
|
+
|
87
|
+
memset(&saddr, 0, sizeof(saddr));
|
88
|
+
saddr.sin_family = AF_INET;
|
89
|
+
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
90
|
+
saddr.sin_port = htons(rd->use_port);
|
91
|
+
|
92
|
+
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
93
|
+
if (sockfd < 0) {
|
94
|
+
perror("socket");
|
95
|
+
return 1;
|
96
|
+
}
|
97
|
+
|
98
|
+
val = 1;
|
99
|
+
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
100
|
+
|
101
|
+
ret = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
|
102
|
+
if (ret < 0) {
|
103
|
+
perror("bind");
|
104
|
+
goto err;
|
105
|
+
}
|
106
|
+
|
107
|
+
ret = listen(sockfd, 1);
|
108
|
+
if (ret < 0) {
|
109
|
+
perror("listen");
|
110
|
+
goto err;
|
111
|
+
}
|
112
|
+
|
113
|
+
pthread_barrier_wait(&rd->connect);
|
114
|
+
|
115
|
+
socklen = sizeof(saddr);
|
116
|
+
use_fd = accept(sockfd, (struct sockaddr *)&saddr, &socklen);
|
117
|
+
if (use_fd < 0) {
|
118
|
+
perror("accept");
|
119
|
+
goto err;
|
120
|
+
}
|
121
|
+
|
122
|
+
rd->accept_fd = use_fd;
|
123
|
+
pthread_barrier_wait(&rd->startup);
|
124
|
+
pthread_barrier_wait(&rd->barrier);
|
125
|
+
|
126
|
+
rd->recv_bytes = rd->max_sends * 4096;
|
127
|
+
arm_recv(ring, rd);
|
128
|
+
*sock = sockfd;
|
129
|
+
return 0;
|
130
|
+
err:
|
131
|
+
close(sockfd);
|
132
|
+
return 1;
|
133
|
+
}
|
134
|
+
|
135
|
+
struct iter {
|
136
|
+
int last_res;
|
137
|
+
int last_id;
|
138
|
+
int count;
|
139
|
+
};
|
140
|
+
|
141
|
+
static void iter_done(struct recv_data *rd, struct iter *iter)
|
142
|
+
{
|
143
|
+
if (!iter->count)
|
144
|
+
return;
|
145
|
+
iter->count = 0;
|
146
|
+
}
|
147
|
+
|
148
|
+
static struct recv_data *last_rd;
|
149
|
+
static int bytes_since_last;
|
150
|
+
|
151
|
+
static int recv_get_cqe(struct io_uring *ring,
|
152
|
+
struct io_uring_cqe **cqe, struct iter *iter)
|
153
|
+
{
|
154
|
+
struct __kernel_timespec ts = { .tv_sec = 0, .tv_nsec = 100000000LL };
|
155
|
+
int ret;
|
156
|
+
|
157
|
+
do {
|
158
|
+
ret = io_uring_submit_and_wait_timeout(ring, cqe, 1, &ts, NULL);
|
159
|
+
if (!ret) {
|
160
|
+
struct recv_data *rd = io_uring_cqe_get_data(*cqe);
|
161
|
+
|
162
|
+
if (last_rd != rd) {
|
163
|
+
if (last_rd) {
|
164
|
+
int diff = bytes_since_last - PER_ITER_LIMIT;
|
165
|
+
|
166
|
+
if (bytes_since_last > PER_ITER_LIMIT &&
|
167
|
+
diff > RECV_BID_SZ)
|
168
|
+
rd->unfair++;
|
169
|
+
}
|
170
|
+
last_rd = rd;
|
171
|
+
bytes_since_last = 0;
|
172
|
+
}
|
173
|
+
if ((*cqe)->res == iter->last_res && rd->id == iter->last_id) {
|
174
|
+
iter->count++;
|
175
|
+
} else {
|
176
|
+
iter_done(rd, iter);
|
177
|
+
}
|
178
|
+
iter->last_res = (*cqe)->res;
|
179
|
+
bytes_since_last += (*cqe)->res;
|
180
|
+
iter->last_id = rd->id;
|
181
|
+
return 0;
|
182
|
+
}
|
183
|
+
if (ret == -ETIME)
|
184
|
+
continue;
|
185
|
+
fprintf(stderr, "wait recv: %d\n", ret);
|
186
|
+
break;
|
187
|
+
} while (1);
|
188
|
+
|
189
|
+
return 1;
|
190
|
+
}
|
191
|
+
|
192
|
+
static int do_recv(struct io_uring *ring)
|
193
|
+
{
|
194
|
+
struct iter iter = { .last_res = -4096, };
|
195
|
+
struct io_uring_cqe *cqe;
|
196
|
+
struct recv_data *rd;
|
197
|
+
int ret = 1;
|
198
|
+
int done = 0;
|
199
|
+
|
200
|
+
last_rd = NULL;
|
201
|
+
bytes_since_last = 0;
|
202
|
+
do {
|
203
|
+
if (recv_get_cqe(ring, &cqe, &iter))
|
204
|
+
break;
|
205
|
+
rd = io_uring_cqe_get_data(cqe);
|
206
|
+
if (cqe->res == -EINVAL) {
|
207
|
+
fprintf(stdout, "recv not supported, skipping\n");
|
208
|
+
return 0;
|
209
|
+
}
|
210
|
+
if (cqe->res < 0) {
|
211
|
+
fprintf(stderr, "failed recv cqe: %d\n", cqe->res);
|
212
|
+
goto err;
|
213
|
+
}
|
214
|
+
if (cqe->res && !(cqe->flags & IORING_CQE_F_BUFFER)) {
|
215
|
+
fprintf(stderr, "no buffer set in recv\n");
|
216
|
+
goto err;
|
217
|
+
}
|
218
|
+
rd->recv_bytes -= cqe->res;
|
219
|
+
rd->bytes_since_arm += cqe->res;
|
220
|
+
rd->total_bytes += cqe->res;
|
221
|
+
if (!cqe->res || !rd->recv_bytes) {
|
222
|
+
io_uring_cqe_seen(ring, cqe);
|
223
|
+
done++;
|
224
|
+
continue;
|
225
|
+
}
|
226
|
+
io_uring_cqe_seen(ring, cqe);
|
227
|
+
if (!(cqe->flags & IORING_CQE_F_MORE) && rd->recv_bytes)
|
228
|
+
arm_recv(ring, rd);
|
229
|
+
} while (done < NR_RDS);
|
230
|
+
|
231
|
+
ret = 0;
|
232
|
+
iter_done(rd, &iter);
|
233
|
+
err:
|
234
|
+
return ret;
|
235
|
+
}
|
236
|
+
|
237
|
+
static void *recv_fn(void *data)
|
238
|
+
{
|
239
|
+
struct recv_data *rds = data;
|
240
|
+
struct io_uring_params p = { };
|
241
|
+
struct io_uring_buf_ring *br = NULL;
|
242
|
+
struct io_uring ring;
|
243
|
+
unsigned int buf_len;
|
244
|
+
void *buf, *ptr;
|
245
|
+
int ret, sock[NR_RDS], i;
|
246
|
+
int brflags, ring_setup = 0;
|
247
|
+
|
248
|
+
for (i = 0; i < NR_RDS; i++) {
|
249
|
+
sock[i] = -1;
|
250
|
+
rds[i].accept_fd = -1;
|
251
|
+
}
|
252
|
+
|
253
|
+
p.cq_entries = 4096;
|
254
|
+
p.flags = rds[0].queue_flags | IORING_SETUP_CQSIZE;
|
255
|
+
ret = io_uring_queue_init_params(16, &ring, &p);
|
256
|
+
if (ret) {
|
257
|
+
if (ret == -EINVAL) {
|
258
|
+
no_limit_support = true;
|
259
|
+
goto skip;
|
260
|
+
}
|
261
|
+
fprintf(stderr, "ring init: %d\n", ret);
|
262
|
+
goto err;
|
263
|
+
}
|
264
|
+
|
265
|
+
ring_setup = 1;
|
266
|
+
if (posix_memalign(&buf, 4096, NR_RDS * rds[0].max_sends * 4096))
|
267
|
+
goto err;
|
268
|
+
|
269
|
+
brflags = 0;
|
270
|
+
br = io_uring_setup_buf_ring(&ring, RECV_BIDS, RECV_BGID, brflags, &ret);
|
271
|
+
if (!br) {
|
272
|
+
if (ret == -EINVAL) {
|
273
|
+
no_limit_support = true;
|
274
|
+
goto skip;
|
275
|
+
}
|
276
|
+
fprintf(stderr, "failed setting up recv ring %d\n", ret);
|
277
|
+
goto err;
|
278
|
+
}
|
279
|
+
|
280
|
+
ptr = buf;
|
281
|
+
buf_len = RECV_BID_SZ;
|
282
|
+
for (i = 0; i < RECV_BIDS; i++) {
|
283
|
+
io_uring_buf_ring_add(br, ptr, buf_len, i, RECV_BID_MASK, i);
|
284
|
+
ptr += buf_len;
|
285
|
+
}
|
286
|
+
io_uring_buf_ring_advance(br, RECV_BIDS);
|
287
|
+
|
288
|
+
for (i = 0; i < NR_RDS; i++) {
|
289
|
+
ret = recv_prep(&ring, &rds[i], &sock[i]);
|
290
|
+
if (ret) {
|
291
|
+
fprintf(stderr, "recv_prep failed: %d\n", ret);
|
292
|
+
goto err;
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
296
|
+
ret = io_uring_submit(&ring);
|
297
|
+
if (ret != NR_RDS) {
|
298
|
+
struct io_uring_cqe *cqe;
|
299
|
+
|
300
|
+
if (!io_uring_peek_cqe(&ring, &cqe)) {
|
301
|
+
if (cqe->res == -EINVAL) {
|
302
|
+
no_limit_support = true;
|
303
|
+
goto skip;
|
304
|
+
}
|
305
|
+
}
|
306
|
+
fprintf(stderr, "submit failed: %d\n", ret);
|
307
|
+
goto err;
|
308
|
+
}
|
309
|
+
|
310
|
+
ret = do_recv(&ring);
|
311
|
+
skip:
|
312
|
+
for (i = 0; i < NR_RDS; i++) {
|
313
|
+
if (sock[i] != -1)
|
314
|
+
close(sock[i]);
|
315
|
+
if (rds[i].accept_fd != -1)
|
316
|
+
close(rds[i].accept_fd);
|
317
|
+
}
|
318
|
+
if (br)
|
319
|
+
io_uring_free_buf_ring(&ring, br, RECV_BIDS, RECV_BGID);
|
320
|
+
if (ring_setup)
|
321
|
+
io_uring_queue_exit(&ring);
|
322
|
+
err:
|
323
|
+
return (void *)(intptr_t)ret;
|
324
|
+
}
|
325
|
+
|
326
|
+
static int do_send(struct recv_data *rd)
|
327
|
+
{
|
328
|
+
struct sockaddr_in saddr = { };
|
329
|
+
int sockfd, ret, i;
|
330
|
+
void *buf;
|
331
|
+
|
332
|
+
buf = malloc(4096);
|
333
|
+
memset(buf, 0xa5, 4096);
|
334
|
+
|
335
|
+
saddr.sin_family = AF_INET;
|
336
|
+
saddr.sin_port = htons(rd->use_port);
|
337
|
+
inet_pton(AF_INET, HOST, &saddr.sin_addr);
|
338
|
+
|
339
|
+
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
340
|
+
if (sockfd < 0) {
|
341
|
+
perror("socket");
|
342
|
+
goto err2;
|
343
|
+
}
|
344
|
+
|
345
|
+
pthread_barrier_wait(&rd->connect);
|
346
|
+
|
347
|
+
ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
|
348
|
+
if (ret < 0) {
|
349
|
+
perror("connect");
|
350
|
+
goto err;
|
351
|
+
}
|
352
|
+
|
353
|
+
pthread_barrier_wait(&rd->startup);
|
354
|
+
|
355
|
+
for (i = 0; i < rd->max_sends; i++) {
|
356
|
+
ret = send(sockfd, buf, 4096, 0);
|
357
|
+
if (ret < 0) {
|
358
|
+
perror("send");
|
359
|
+
return 1;
|
360
|
+
} else if (ret != 4096) {
|
361
|
+
printf("short send\n");
|
362
|
+
goto err;
|
363
|
+
}
|
364
|
+
}
|
365
|
+
|
366
|
+
pthread_barrier_wait(&rd->barrier);
|
367
|
+
close(sockfd);
|
368
|
+
free(buf);
|
369
|
+
return 0;
|
370
|
+
err:
|
371
|
+
close(sockfd);
|
372
|
+
err2:
|
373
|
+
free(buf);
|
374
|
+
return 1;
|
375
|
+
}
|
376
|
+
|
377
|
+
struct res {
|
378
|
+
int mshot_too_big;
|
379
|
+
int unfair;
|
380
|
+
};
|
381
|
+
|
382
|
+
static int test(int nr_send, int bundle, unsigned int queue_flags, struct res *r)
|
383
|
+
{
|
384
|
+
struct recv_data rds[NR_RDS] = { };
|
385
|
+
pthread_t recv_thread;
|
386
|
+
int ret, i;
|
387
|
+
void *retval;
|
388
|
+
|
389
|
+
memset(r, 0, sizeof(*r));
|
390
|
+
|
391
|
+
for (i = 0; i < NR_RDS; i++) {
|
392
|
+
struct recv_data *rd = &rds[i];
|
393
|
+
|
394
|
+
rd->use_port = ++use_port;
|
395
|
+
|
396
|
+
pthread_barrier_init(&rd->connect, NULL, 2);
|
397
|
+
pthread_barrier_init(&rd->startup, NULL, 2);
|
398
|
+
pthread_barrier_init(&rd->barrier, NULL, 2);
|
399
|
+
|
400
|
+
rd->queue_flags = queue_flags;
|
401
|
+
rd->max_sends = nr_send;
|
402
|
+
rd->recv_bundle = bundle;
|
403
|
+
rd->recv_bytes = nr_send * 4096;
|
404
|
+
rd->id = i + 1;
|
405
|
+
}
|
406
|
+
|
407
|
+
ret = pthread_create(&recv_thread, NULL, recv_fn, rds);
|
408
|
+
if (ret) {
|
409
|
+
fprintf(stderr, "Thread create failed: %d\n", ret);
|
410
|
+
return 1;
|
411
|
+
}
|
412
|
+
|
413
|
+
for (i = 0; i < NR_RDS; i++) {
|
414
|
+
struct recv_data *rd = &rds[i];
|
415
|
+
|
416
|
+
ret = do_send(rd);
|
417
|
+
if (ret)
|
418
|
+
return ret;
|
419
|
+
}
|
420
|
+
|
421
|
+
pthread_join(recv_thread, &retval);
|
422
|
+
|
423
|
+
for (i = 0; i < NR_RDS; i++) {
|
424
|
+
struct recv_data *rd = &rds[i];
|
425
|
+
|
426
|
+
r->mshot_too_big += rd->mshot_too_big;
|
427
|
+
r->unfair += rd->unfair;
|
428
|
+
}
|
429
|
+
|
430
|
+
return (intptr_t) retval;
|
431
|
+
}
|
432
|
+
|
433
|
+
static int run_tests(void)
|
434
|
+
{
|
435
|
+
struct res r;
|
436
|
+
int ret;
|
437
|
+
|
438
|
+
ret = test(2, 1, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER, &r);
|
439
|
+
if (ret) {
|
440
|
+
if (no_limit_support)
|
441
|
+
return T_EXIT_SKIP;
|
442
|
+
fprintf(stderr, "test DEFER bundle failed\n");
|
443
|
+
return T_EXIT_FAIL;
|
444
|
+
}
|
445
|
+
|
446
|
+
/* DEFER_TASKRUN should be fully fair and not have overshoots */
|
447
|
+
if (r.unfair || r.mshot_too_big) {
|
448
|
+
fprintf(stderr, "DEFER bundle unfair=%d, too_big=%d\n", r.unfair, r.mshot_too_big);
|
449
|
+
return T_EXIT_FAIL;
|
450
|
+
}
|
451
|
+
|
452
|
+
ret = test(2, 0, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER, &r);
|
453
|
+
if (ret) {
|
454
|
+
fprintf(stderr, "test DEFER failed\n");
|
455
|
+
return T_EXIT_FAIL;
|
456
|
+
}
|
457
|
+
|
458
|
+
/* DEFER_TASKRUN should be fully fair and not have overshoots */
|
459
|
+
if (r.unfair || r.mshot_too_big) {
|
460
|
+
fprintf(stderr, "DEFER unfair=%d, too_big=%d\n", r.unfair, r.mshot_too_big);
|
461
|
+
return T_EXIT_FAIL;
|
462
|
+
}
|
463
|
+
|
464
|
+
ret = test(2, 1, IORING_SETUP_COOP_TASKRUN, &r);
|
465
|
+
if (ret) {
|
466
|
+
fprintf(stderr, "test COOP bundle failed\n");
|
467
|
+
return T_EXIT_FAIL;
|
468
|
+
}
|
469
|
+
|
470
|
+
/*
|
471
|
+
* normal task_work should not have overshoots, but may not be fair
|
472
|
+
* because of the re-arming.
|
473
|
+
*/
|
474
|
+
if (r.unfair)
|
475
|
+
fprintf(stdout, "!DEFER bundle unfair, expected\n");
|
476
|
+
if (r.mshot_too_big) {
|
477
|
+
fprintf(stderr, "!DEFER bundle too_big=%d\n", r.mshot_too_big);
|
478
|
+
return T_EXIT_FAIL;
|
479
|
+
}
|
480
|
+
|
481
|
+
ret = test(2, 0, IORING_SETUP_COOP_TASKRUN, &r);
|
482
|
+
if (ret) {
|
483
|
+
fprintf(stderr, "test COOP failed\n");
|
484
|
+
return T_EXIT_FAIL;
|
485
|
+
}
|
486
|
+
|
487
|
+
/*
|
488
|
+
* normal task_work should not have overshoots, but may not be fair
|
489
|
+
* because of the re-arming.
|
490
|
+
*/
|
491
|
+
if (r.unfair)
|
492
|
+
fprintf(stdout, "!DEFER unfair, expected\n");
|
493
|
+
if (r.mshot_too_big) {
|
494
|
+
fprintf(stderr, "!DEFER too_big=%d\n", r.mshot_too_big);
|
495
|
+
return T_EXIT_FAIL;
|
496
|
+
}
|
497
|
+
|
498
|
+
return T_EXIT_PASS;
|
499
|
+
}
|
500
|
+
|
501
|
+
int main(int argc, char *argv[])
|
502
|
+
{
|
503
|
+
int ret;
|
504
|
+
|
505
|
+
if (argc > 1)
|
506
|
+
return T_EXIT_SKIP;
|
507
|
+
|
508
|
+
ret = run_tests();
|
509
|
+
if (ret != T_EXIT_PASS)
|
510
|
+
return ret;
|
511
|
+
|
512
|
+
return T_EXIT_PASS;
|
513
|
+
}
|
@@ -213,16 +213,16 @@ static int test_wait_arg(void)
|
|
213
213
|
return T_EXIT_FAIL;
|
214
214
|
}
|
215
215
|
|
216
|
-
buffer =
|
216
|
+
buffer = t_aligned_alloc(page_size, page_size * 4);
|
217
217
|
if (!buffer) {
|
218
218
|
fprintf(stderr, "allocation failed\n");
|
219
219
|
return T_EXIT_FAIL;
|
220
220
|
}
|
221
221
|
|
222
|
-
rd.user_addr = (
|
222
|
+
rd.user_addr = uring_ptr_to_u64(buffer);
|
223
223
|
rd.size = page_size;
|
224
224
|
rd.flags = IORING_MEM_REGION_TYPE_USER;
|
225
|
-
mr.region_uptr = (
|
225
|
+
mr.region_uptr = uring_ptr_to_u64(&rd);
|
226
226
|
mr.flags = IORING_MEM_REGION_REG_WAIT_ARG;
|
227
227
|
|
228
228
|
ret = io_uring_register_region(&ring, &mr);
|
@@ -281,17 +281,17 @@ static int test_regions(void)
|
|
281
281
|
void *buffer;
|
282
282
|
int ret;
|
283
283
|
|
284
|
-
buffer =
|
284
|
+
buffer = t_aligned_alloc(page_size, page_size * 4);
|
285
285
|
if (!buffer) {
|
286
286
|
fprintf(stderr, "allocation failed\n");
|
287
287
|
return T_EXIT_FAIL;
|
288
288
|
}
|
289
289
|
|
290
|
-
rd.user_addr = (
|
290
|
+
rd.user_addr = uring_ptr_to_u64(buffer);
|
291
291
|
rd.size = page_size;
|
292
292
|
rd.flags = IORING_MEM_REGION_TYPE_USER;
|
293
293
|
|
294
|
-
mr.region_uptr = (
|
294
|
+
mr.region_uptr = uring_ptr_to_u64(&rd);
|
295
295
|
mr.flags = IORING_MEM_REGION_REG_WAIT_ARG;
|
296
296
|
|
297
297
|
ret = test_try_register_region(&mr, true);
|
@@ -324,7 +324,7 @@ static int test_regions(void)
|
|
324
324
|
fprintf(stderr, "test_try_register_region() null uptr fail %i\n", ret);
|
325
325
|
return T_EXIT_FAIL;
|
326
326
|
}
|
327
|
-
rd.user_addr = (
|
327
|
+
rd.user_addr = uring_ptr_to_u64(buffer);
|
328
328
|
|
329
329
|
rd.flags = 0;
|
330
330
|
ret = test_try_register_region(&mr, true);
|
@@ -348,7 +348,7 @@ static int test_regions(void)
|
|
348
348
|
fprintf(stderr, "test_try_register_region() NULL region %i\n", ret);
|
349
349
|
return T_EXIT_FAIL;
|
350
350
|
}
|
351
|
-
mr.region_uptr = (
|
351
|
+
mr.region_uptr = uring_ptr_to_u64(&rd);
|
352
352
|
|
353
353
|
rd.user_addr += 16;
|
354
354
|
ret = test_try_register_region(&mr, true);
|
@@ -363,7 +363,7 @@ static int test_regions(void)
|
|
363
363
|
fprintf(stderr, "test_try_register_region() bogus uptr %i\n", ret);
|
364
364
|
return T_EXIT_FAIL;
|
365
365
|
}
|
366
|
-
rd.user_addr = (
|
366
|
+
rd.user_addr = uring_ptr_to_u64(buffer);
|
367
367
|
free(buffer);
|
368
368
|
|
369
369
|
buffer = mmap(NULL, page_size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
@@ -372,7 +372,7 @@ static int test_regions(void)
|
|
372
372
|
return 1;
|
373
373
|
}
|
374
374
|
|
375
|
-
rd.user_addr = (
|
375
|
+
rd.user_addr = uring_ptr_to_u64(buffer);
|
376
376
|
ret = test_try_register_region(&mr, true);
|
377
377
|
if (ret != -EFAULT) {
|
378
378
|
fprintf(stderr, "test_try_register_region() RO uptr %i\n", ret);
|
@@ -393,7 +393,7 @@ static int test_regions(void)
|
|
393
393
|
|
394
394
|
has_kernel_regions = true;
|
395
395
|
rd.flags = 0;
|
396
|
-
rd.user_addr = (
|
396
|
+
rd.user_addr = uring_ptr_to_u64(buffer);
|
397
397
|
ret = test_try_register_region(&mr, true);
|
398
398
|
if (!ret) {
|
399
399
|
fprintf(stderr, "test_try_register_region() failed uptr w kernel alloc %i\n", ret);
|
@@ -421,7 +421,7 @@ static int t_region_create_kernel(struct t_region *r,
|
|
421
421
|
{
|
422
422
|
struct io_uring_region_desc rd = { .size = r->size, };
|
423
423
|
struct io_uring_mem_region_reg mr = {
|
424
|
-
.region_uptr = (
|
424
|
+
.region_uptr = uring_ptr_to_u64(&rd),
|
425
425
|
.flags = IORING_MEM_REGION_REG_WAIT_ARG,
|
426
426
|
};
|
427
427
|
void *p;
|
@@ -458,9 +458,9 @@ static int t_region_create_user(struct t_region *r,
|
|
458
458
|
if (p == MAP_FAILED)
|
459
459
|
return -ENOMEM;
|
460
460
|
|
461
|
-
mr.region_uptr = (
|
461
|
+
mr.region_uptr = uring_ptr_to_u64(&rd);
|
462
462
|
mr.flags = IORING_MEM_REGION_REG_WAIT_ARG;
|
463
|
-
rd.user_addr = (
|
463
|
+
rd.user_addr = uring_ptr_to_u64(p);
|
464
464
|
rd.flags = IORING_MEM_REGION_TYPE_USER;
|
465
465
|
rd.size = r->size;
|
466
466
|
|
@@ -842,8 +842,8 @@ int main(int argc, char *argv[])
|
|
842
842
|
|
843
843
|
if (try_hugepages) {
|
844
844
|
len = LARGE_BUF_SIZE;
|
845
|
-
tx_buffer =
|
846
|
-
rx_buffer =
|
845
|
+
tx_buffer = t_aligned_alloc(page_sz, len);
|
846
|
+
rx_buffer = t_aligned_alloc(page_sz, len);
|
847
847
|
|
848
848
|
if (tx_buffer && rx_buffer) {
|
849
849
|
buffers_iov[BUF_T_LARGE].iov_base = tx_buffer;
|
@@ -856,8 +856,8 @@ int main(int argc, char *argv[])
|
|
856
856
|
|
857
857
|
if (!tx_buffer) {
|
858
858
|
len = 2 * page_sz;
|
859
|
-
tx_buffer =
|
860
|
-
rx_buffer =
|
859
|
+
tx_buffer = t_aligned_alloc(page_sz, len);
|
860
|
+
rx_buffer = t_aligned_alloc(page_sz, len);
|
861
861
|
|
862
862
|
if (!tx_buffer || !rx_buffer) {
|
863
863
|
fprintf(stderr, "can't allocate buffers\n");
|
@@ -0,0 +1,81 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: Check that trying to read two eventfd events will still
|
4
|
+
* return one when generated. There was a kernel commit that
|
5
|
+
* all of a sudden pretended that anonymous inodes were
|
6
|
+
* regular files, which broke the io_uring short read/write
|
7
|
+
* handling logic. See:
|
8
|
+
*
|
9
|
+
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cfd86ef7e8e7
|
10
|
+
*/
|
11
|
+
#include <errno.h>
|
12
|
+
#include <stdio.h>
|
13
|
+
#include <unistd.h>
|
14
|
+
#include <stdlib.h>
|
15
|
+
#include <string.h>
|
16
|
+
#include <fcntl.h>
|
17
|
+
#include <sys/timerfd.h>
|
18
|
+
|
19
|
+
#include "liburing.h"
|
20
|
+
#include "helpers.h"
|
21
|
+
|
22
|
+
static void sig_alrm(int sig)
|
23
|
+
{
|
24
|
+
fprintf(stderr, "Test failed due to timeout\n");
|
25
|
+
exit(T_EXIT_FAIL);
|
26
|
+
}
|
27
|
+
|
28
|
+
int main(int argc, char *argv[])
|
29
|
+
{
|
30
|
+
struct io_uring_params p = {};
|
31
|
+
struct sigaction act = { };
|
32
|
+
struct io_uring_sqe *sqe;
|
33
|
+
struct io_uring_cqe *cqe;
|
34
|
+
struct io_uring ring;
|
35
|
+
struct itimerspec is = { };
|
36
|
+
unsigned long tmp[2];
|
37
|
+
int ret, fd;
|
38
|
+
|
39
|
+
if (argc > 1)
|
40
|
+
return T_EXIT_SKIP;
|
41
|
+
|
42
|
+
ret = io_uring_queue_init_params(8, &ring, &p);
|
43
|
+
if (ret) {
|
44
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
45
|
+
return T_EXIT_FAIL;
|
46
|
+
}
|
47
|
+
|
48
|
+
fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
|
49
|
+
if (fd < 0) {
|
50
|
+
perror("timerfd_create");
|
51
|
+
return T_EXIT_FAIL;
|
52
|
+
}
|
53
|
+
|
54
|
+
sqe = io_uring_get_sqe(&ring);
|
55
|
+
io_uring_prep_read(sqe, fd, tmp, sizeof(tmp), 0);
|
56
|
+
sqe->user_data = 1;
|
57
|
+
|
58
|
+
io_uring_submit(&ring);
|
59
|
+
|
60
|
+
is.it_value.tv_sec = 0;
|
61
|
+
is.it_value.tv_nsec = 10000000;
|
62
|
+
ret = timerfd_settime(fd, 0, &is, NULL);
|
63
|
+
if (ret < 0) {
|
64
|
+
perror("timerfd_settime");
|
65
|
+
return T_EXIT_FAIL;
|
66
|
+
}
|
67
|
+
|
68
|
+
act.sa_handler = sig_alrm;
|
69
|
+
sigaction(SIGALRM, &act, NULL);
|
70
|
+
alarm(1);
|
71
|
+
|
72
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
73
|
+
if (ret) {
|
74
|
+
fprintf(stderr, "wait: %d\n", ret);
|
75
|
+
return T_EXIT_FAIL;
|
76
|
+
}
|
77
|
+
|
78
|
+
close(fd);
|
79
|
+
io_uring_cqe_seen(&ring, cqe);
|
80
|
+
return T_EXIT_PASS;
|
81
|
+
}
|