uringmachine 0.3 → 0.4
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/CHANGELOG.md +9 -0
- data/README.md +85 -0
- data/TODO.md +5 -0
- data/examples/echo_server.rb +18 -40
- data/examples/inout.rb +19 -0
- data/examples/nc.rb +36 -0
- data/ext/um/extconf.rb +6 -15
- data/ext/um/um.c +245 -53
- data/ext/um/um.h +21 -9
- data/ext/um/um_class.c +74 -87
- data/ext/um/um_const.c +184 -0
- data/ext/um/um_op.c +10 -13
- data/ext/um/um_utils.c +48 -3
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +12 -0
- data/test/helper.rb +8 -0
- data/test/test_um.rb +227 -7
- data/vendor/liburing/.github/workflows/build.yml +29 -1
- data/vendor/liburing/.gitignore +1 -0
- data/vendor/liburing/CHANGELOG +15 -0
- data/vendor/liburing/CONTRIBUTING.md +165 -0
- data/vendor/liburing/configure +32 -0
- data/vendor/liburing/examples/Makefile +8 -1
- data/vendor/liburing/examples/kdigest.c +405 -0
- data/vendor/liburing/examples/proxy.c +75 -8
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/src/Makefile +16 -2
- data/vendor/liburing/src/include/liburing/io_uring.h +31 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
- data/vendor/liburing/src/include/liburing.h +31 -4
- data/vendor/liburing/src/liburing-ffi.map +5 -0
- data/vendor/liburing/src/liburing.map +1 -0
- data/vendor/liburing/src/queue.c +3 -0
- data/vendor/liburing/src/register.c +36 -0
- data/vendor/liburing/src/sanitize.c +176 -0
- data/vendor/liburing/src/setup.c +1 -1
- data/vendor/liburing/test/35fa71a030ca.c +7 -0
- data/vendor/liburing/test/500f9fbadef8.c +2 -0
- data/vendor/liburing/test/7ad0e4b2f83c.c +0 -25
- data/vendor/liburing/test/917257daa0fe.c +7 -0
- data/vendor/liburing/test/Makefile +31 -4
- data/vendor/liburing/test/a0908ae19763.c +7 -0
- data/vendor/liburing/test/a4c0b3decb33.c +7 -0
- data/vendor/liburing/test/accept.c +14 -4
- data/vendor/liburing/test/b19062a56726.c +7 -0
- data/vendor/liburing/test/bind-listen.c +2 -2
- data/vendor/liburing/test/buf-ring-nommap.c +10 -3
- data/vendor/liburing/test/buf-ring.c +2 -0
- data/vendor/liburing/test/coredump.c +7 -0
- data/vendor/liburing/test/cq-overflow.c +13 -1
- data/vendor/liburing/test/d4ae271dfaae.c +11 -3
- data/vendor/liburing/test/defer-taskrun.c +2 -2
- data/vendor/liburing/test/defer-tw-timeout.c +4 -1
- data/vendor/liburing/test/defer.c +2 -2
- data/vendor/liburing/test/double-poll-crash.c +1 -1
- data/vendor/liburing/test/eeed8b54e0df.c +2 -0
- data/vendor/liburing/test/eventfd.c +0 -1
- data/vendor/liburing/test/exit-no-cleanup.c +11 -0
- data/vendor/liburing/test/fadvise.c +9 -26
- data/vendor/liburing/test/fdinfo.c +9 -1
- data/vendor/liburing/test/file-register.c +14 -2
- data/vendor/liburing/test/file-update.c +1 -1
- data/vendor/liburing/test/file-verify.c +27 -16
- data/vendor/liburing/test/files-exit-hang-timeout.c +1 -2
- data/vendor/liburing/test/fixed-buf-iter.c +3 -1
- data/vendor/liburing/test/fixed-hugepage.c +12 -1
- data/vendor/liburing/test/fsnotify.c +1 -0
- data/vendor/liburing/test/futex.c +16 -4
- data/vendor/liburing/test/helpers.c +47 -0
- data/vendor/liburing/test/helpers.h +6 -0
- data/vendor/liburing/test/init-mem.c +5 -3
- data/vendor/liburing/test/io-cancel.c +0 -24
- data/vendor/liburing/test/io_uring_passthrough.c +2 -0
- data/vendor/liburing/test/io_uring_register.c +25 -6
- data/vendor/liburing/test/iopoll-leak.c +4 -0
- data/vendor/liburing/test/iopoll-overflow.c +1 -1
- data/vendor/liburing/test/iopoll.c +3 -3
- data/vendor/liburing/test/kallsyms.c +203 -0
- data/vendor/liburing/test/link-timeout.c +159 -0
- data/vendor/liburing/test/linked-defer-close.c +224 -0
- data/vendor/liburing/test/madvise.c +12 -25
- data/vendor/liburing/test/min-timeout-wait.c +0 -25
- data/vendor/liburing/test/min-timeout.c +0 -25
- data/vendor/liburing/test/mkdir.c +6 -0
- data/vendor/liburing/test/msg-ring.c +8 -2
- data/vendor/liburing/test/napi-test.c +15 -2
- data/vendor/liburing/test/no-mmap-inval.c +2 -0
- data/vendor/liburing/test/nop.c +44 -0
- data/vendor/liburing/test/ooo-file-unreg.c +1 -1
- data/vendor/liburing/test/open-close.c +40 -0
- data/vendor/liburing/test/openat2.c +37 -14
- data/vendor/liburing/test/poll-many.c +13 -7
- data/vendor/liburing/test/poll-mshot-update.c +17 -10
- data/vendor/liburing/test/poll-v-poll.c +6 -3
- data/vendor/liburing/test/pollfree.c +148 -0
- data/vendor/liburing/test/read-mshot-empty.c +156 -153
- data/vendor/liburing/test/read-mshot.c +276 -27
- data/vendor/liburing/test/read-write.c +78 -13
- data/vendor/liburing/test/recv-msgall-stream.c +3 -0
- data/vendor/liburing/test/recv-msgall.c +5 -0
- data/vendor/liburing/test/recvsend_bundle-inc.c +680 -0
- data/vendor/liburing/test/recvsend_bundle.c +92 -29
- data/vendor/liburing/test/reg-fd-only.c +14 -4
- data/vendor/liburing/test/regbuf-clone.c +187 -0
- data/vendor/liburing/test/regbuf-merge.c +7 -0
- data/vendor/liburing/test/register-restrictions.c +86 -85
- data/vendor/liburing/test/rename.c +59 -1
- data/vendor/liburing/test/ringbuf-read.c +5 -0
- data/vendor/liburing/test/ringbuf-status.c +5 -1
- data/vendor/liburing/test/runtests.sh +16 -1
- data/vendor/liburing/test/send-zerocopy.c +59 -0
- data/vendor/liburing/test/short-read.c +1 -0
- data/vendor/liburing/test/socket.c +43 -0
- data/vendor/liburing/test/splice.c +3 -1
- data/vendor/liburing/test/sq-poll-dup.c +1 -1
- data/vendor/liburing/test/sq-poll-share.c +2 -0
- data/vendor/liburing/test/sqpoll-disable-exit.c +8 -0
- data/vendor/liburing/test/sqpoll-exit-hang.c +1 -25
- data/vendor/liburing/test/sqpoll-sleep.c +1 -25
- data/vendor/liburing/test/statx.c +89 -0
- data/vendor/liburing/test/stdout.c +2 -0
- data/vendor/liburing/test/submit-and-wait.c +1 -25
- data/vendor/liburing/test/submit-reuse.c +4 -26
- data/vendor/liburing/test/symlink.c +12 -1
- data/vendor/liburing/test/sync-cancel.c +48 -21
- data/vendor/liburing/test/thread-exit.c +5 -0
- data/vendor/liburing/test/timeout-new.c +1 -26
- data/vendor/liburing/test/timeout.c +12 -26
- data/vendor/liburing/test/unlink.c +94 -1
- data/vendor/liburing/test/uring_cmd_ublk.c +1252 -0
- data/vendor/liburing/test/waitid.c +62 -8
- data/vendor/liburing/test/wq-aff.c +35 -0
- data/vendor/liburing/test/xfail_prep_link_timeout_out_of_scope.c +46 -0
- data/vendor/liburing/test/xfail_register_buffers_out_of_scope.c +51 -0
- metadata +17 -4
- data/examples/event_loop.rb +0 -69
- data/examples/fibers.rb +0 -105
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: test pollfree wakeups
|
|
4
|
+
*/
|
|
5
|
+
#include <fcntl.h>
|
|
6
|
+
#include <stdio.h>
|
|
7
|
+
#include <string.h>
|
|
8
|
+
#include <sys/stat.h>
|
|
9
|
+
#include <sys/types.h>
|
|
10
|
+
#include <sys/signalfd.h>
|
|
11
|
+
#include <unistd.h>
|
|
12
|
+
#include <stdlib.h>
|
|
13
|
+
|
|
14
|
+
#include "liburing.h"
|
|
15
|
+
#include "helpers.h"
|
|
16
|
+
|
|
17
|
+
static int no_signalfd;
|
|
18
|
+
|
|
19
|
+
static int child(int flags)
|
|
20
|
+
{
|
|
21
|
+
struct io_uring_sqe *sqe;
|
|
22
|
+
struct io_uring ring;
|
|
23
|
+
struct signalfd_siginfo si;
|
|
24
|
+
static unsigned long index;
|
|
25
|
+
sigset_t mask;
|
|
26
|
+
int ret, fd;
|
|
27
|
+
|
|
28
|
+
ret = io_uring_queue_init(4, &ring, flags);
|
|
29
|
+
if (ret) {
|
|
30
|
+
if (ret == -EINVAL)
|
|
31
|
+
return 0;
|
|
32
|
+
fprintf(stderr, "queue init failed %d\n", ret);
|
|
33
|
+
return ret;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
sigemptyset(&mask);
|
|
37
|
+
sigaddset(&mask, SIGINT);
|
|
38
|
+
|
|
39
|
+
fd = signalfd(-1, &mask, SFD_NONBLOCK);
|
|
40
|
+
if (fd < 0) {
|
|
41
|
+
no_signalfd = 1;
|
|
42
|
+
perror("signalfd");
|
|
43
|
+
return 1;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
sqe = io_uring_get_sqe(&ring);
|
|
47
|
+
io_uring_prep_read(sqe, fd, &si, sizeof(si), 0);
|
|
48
|
+
sqe->user_data = 1;
|
|
49
|
+
io_uring_submit(&ring);
|
|
50
|
+
|
|
51
|
+
sqe = io_uring_get_sqe(&ring);
|
|
52
|
+
io_uring_prep_read(sqe, fd, &si, sizeof(si), 0);
|
|
53
|
+
sqe->user_data = 2;
|
|
54
|
+
sqe->flags |= IOSQE_ASYNC;
|
|
55
|
+
io_uring_submit(&ring);
|
|
56
|
+
|
|
57
|
+
sqe = io_uring_get_sqe(&ring);
|
|
58
|
+
io_uring_prep_read(sqe, fd, &si, sizeof(si), 0);
|
|
59
|
+
sqe->user_data = 3;
|
|
60
|
+
io_uring_submit(&ring);
|
|
61
|
+
|
|
62
|
+
if (!(++index & 7))
|
|
63
|
+
usleep(100);
|
|
64
|
+
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static int run_test(int flags)
|
|
69
|
+
{
|
|
70
|
+
pid_t pid;
|
|
71
|
+
int ret;
|
|
72
|
+
|
|
73
|
+
pid = fork();
|
|
74
|
+
if (pid < 0) {
|
|
75
|
+
perror("fork");
|
|
76
|
+
return 1;
|
|
77
|
+
} else if (!pid) {
|
|
78
|
+
ret = child(flags);
|
|
79
|
+
_exit(ret);
|
|
80
|
+
} else {
|
|
81
|
+
int wstatus;
|
|
82
|
+
pid_t childpid;
|
|
83
|
+
|
|
84
|
+
do {
|
|
85
|
+
childpid = waitpid(pid, &wstatus, 0);
|
|
86
|
+
} while (childpid == (pid_t) -1 && (errno == EINTR));
|
|
87
|
+
|
|
88
|
+
if (errno == ECHILD)
|
|
89
|
+
wstatus = 0;
|
|
90
|
+
return wstatus;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
static int test(int flags)
|
|
95
|
+
{
|
|
96
|
+
struct timeval start;
|
|
97
|
+
int ret;
|
|
98
|
+
|
|
99
|
+
gettimeofday(&start, NULL);
|
|
100
|
+
do {
|
|
101
|
+
ret = run_test(flags);
|
|
102
|
+
if (ret) {
|
|
103
|
+
fprintf(stderr, "test failed with flags %x\n", flags);
|
|
104
|
+
return 1;
|
|
105
|
+
}
|
|
106
|
+
if (no_signalfd)
|
|
107
|
+
break;
|
|
108
|
+
} while (mtime_since_now(&start) < 2500);
|
|
109
|
+
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
int main(int argc, char *argv[])
|
|
114
|
+
{
|
|
115
|
+
int ret;
|
|
116
|
+
|
|
117
|
+
if (argc > 1)
|
|
118
|
+
return T_EXIT_SKIP;
|
|
119
|
+
|
|
120
|
+
ret = test(0);
|
|
121
|
+
if (ret) {
|
|
122
|
+
fprintf(stderr, "test 0 failed: %d\n", ret);
|
|
123
|
+
return ret;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (no_signalfd)
|
|
127
|
+
return T_EXIT_SKIP;
|
|
128
|
+
|
|
129
|
+
ret = test(IORING_SETUP_SQPOLL);
|
|
130
|
+
if (ret) {
|
|
131
|
+
fprintf(stderr, "test SQPOLL failed: %d\n", ret);
|
|
132
|
+
return ret;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
ret = test(IORING_SETUP_COOP_TASKRUN);
|
|
136
|
+
if (ret) {
|
|
137
|
+
fprintf(stderr, "test COOP failed: %d\n", ret);
|
|
138
|
+
return ret;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
ret = test(IORING_SETUP_DEFER_TASKRUN|IORING_SETUP_SINGLE_ISSUER);
|
|
142
|
+
if (ret) {
|
|
143
|
+
fprintf(stderr, "test DEFER failed: %d\n", ret);
|
|
144
|
+
return ret;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return T_EXIT_PASS;
|
|
148
|
+
}
|
|
@@ -1,153 +1,156 @@
|
|
|
1
|
-
/* SPDX-License-Identifier: MIT */
|
|
2
|
-
/*
|
|
3
|
-
* Description: test that multishot read correctly keeps reading until all
|
|
4
|
-
* data has been emptied. the original implementation failed
|
|
5
|
-
* to do so, if the available buffer size was less than what
|
|
6
|
-
* was available, hence requiring multiple reads to empty the
|
|
7
|
-
* file buffer.
|
|
8
|
-
*/
|
|
9
|
-
#include <stdio.h>
|
|
10
|
-
#include <unistd.h>
|
|
11
|
-
#include <stdlib.h>
|
|
12
|
-
#include <string.h>
|
|
13
|
-
#include <assert.h>
|
|
14
|
-
#include <pthread.h>
|
|
15
|
-
#include <sys/time.h>
|
|
16
|
-
|
|
17
|
-
#include "liburing.h"
|
|
18
|
-
#include "helpers.h"
|
|
19
|
-
|
|
20
|
-
#define BGID 17
|
|
21
|
-
#define NR_BUFS 4
|
|
22
|
-
#define BR_MASK (NR_BUFS - 1)
|
|
23
|
-
#define BUF_SIZE 32
|
|
24
|
-
|
|
25
|
-
static int do_write(int fd, void *buf, int buf_size)
|
|
26
|
-
{
|
|
27
|
-
int ret;
|
|
28
|
-
|
|
29
|
-
ret = write(fd, buf, buf_size);
|
|
30
|
-
if (ret < 0) {
|
|
31
|
-
perror("write");
|
|
32
|
-
return 0;
|
|
33
|
-
} else if (ret != buf_size) {
|
|
34
|
-
fprintf(stderr, "bad write size %d\n", ret);
|
|
35
|
-
return 0;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return 1;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
static void *thread_fn(void *data)
|
|
42
|
-
{
|
|
43
|
-
char w1[BUF_SIZE], w2[BUF_SIZE];
|
|
44
|
-
int *fds = data;
|
|
45
|
-
|
|
46
|
-
memset(w1, 0x11, BUF_SIZE);
|
|
47
|
-
memset(w2, 0x22, BUF_SIZE);
|
|
48
|
-
|
|
49
|
-
if (!do_write(fds[1], w1, BUF_SIZE))
|
|
50
|
-
return NULL;
|
|
51
|
-
if (!do_write(fds[1], w2, BUF_SIZE))
|
|
52
|
-
return NULL;
|
|
53
|
-
|
|
54
|
-
usleep(100000);
|
|
55
|
-
|
|
56
|
-
if (!do_write(fds[1], w1, BUF_SIZE))
|
|
57
|
-
return NULL;
|
|
58
|
-
if (!do_write(fds[1], w2, BUF_SIZE))
|
|
59
|
-
return NULL;
|
|
60
|
-
|
|
61
|
-
return NULL;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
int main(int argc, char *argv[])
|
|
65
|
-
{
|
|
66
|
-
struct io_uring_buf_ring *br;
|
|
67
|
-
struct io_uring_sqe *sqe;
|
|
68
|
-
struct io_uring_cqe *cqe;
|
|
69
|
-
struct io_uring ring;
|
|
70
|
-
pthread_t thread;
|
|
71
|
-
int i, ret, fds[2];
|
|
72
|
-
void *buf, *tret;
|
|
73
|
-
|
|
74
|
-
if (argc > 1)
|
|
75
|
-
return T_EXIT_SKIP;
|
|
76
|
-
|
|
77
|
-
if (pipe(fds) < 0) {
|
|
78
|
-
perror("pipe");
|
|
79
|
-
return T_EXIT_FAIL;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
ret = io_uring_queue_init(8, &ring, 0);
|
|
83
|
-
if (ret) {
|
|
84
|
-
fprintf(stderr, "queue_init: %d\n", ret);
|
|
85
|
-
return T_EXIT_FAIL;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
br = io_uring_setup_buf_ring(&ring, NR_BUFS, BGID, 0, &ret);
|
|
89
|
-
if (!br) {
|
|
90
|
-
if (ret == -EINVAL)
|
|
91
|
-
return T_EXIT_SKIP;
|
|
92
|
-
fprintf(stderr, "failed buffer ring %d\n", ret);
|
|
93
|
-
return T_EXIT_FAIL;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
buf = malloc(NR_BUFS * BUF_SIZE);
|
|
97
|
-
for (i = 0; i < NR_BUFS; i++) {
|
|
98
|
-
void *this_buf = buf + i * BUF_SIZE;
|
|
99
|
-
|
|
100
|
-
io_uring_buf_ring_add(br, this_buf, BUF_SIZE, i, BR_MASK, i);
|
|
101
|
-
}
|
|
102
|
-
io_uring_buf_ring_advance(br, NR_BUFS);
|
|
103
|
-
|
|
104
|
-
sqe = io_uring_get_sqe(&ring);
|
|
105
|
-
io_uring_prep_read_multishot(sqe, fds[0], 0, 0, BGID);
|
|
106
|
-
|
|
107
|
-
ret = io_uring_submit(&ring);
|
|
108
|
-
if (ret != 1) {
|
|
109
|
-
fprintf(stderr, "bad submit %d\n", ret);
|
|
110
|
-
return T_EXIT_FAIL;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/*
|
|
114
|
-
* read multishot not available would be ready as a cqe when
|
|
115
|
-
* submission returns, check and skip if not.
|
|
116
|
-
*/
|
|
117
|
-
ret = io_uring_peek_cqe(&ring, &cqe);
|
|
118
|
-
if (!ret) {
|
|
119
|
-
if (cqe->res == -EINVAL || cqe->res == -EBADF)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: test that multishot read correctly keeps reading until all
|
|
4
|
+
* data has been emptied. the original implementation failed
|
|
5
|
+
* to do so, if the available buffer size was less than what
|
|
6
|
+
* was available, hence requiring multiple reads to empty the
|
|
7
|
+
* file buffer.
|
|
8
|
+
*/
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
#include <unistd.h>
|
|
11
|
+
#include <stdlib.h>
|
|
12
|
+
#include <string.h>
|
|
13
|
+
#include <assert.h>
|
|
14
|
+
#include <pthread.h>
|
|
15
|
+
#include <sys/time.h>
|
|
16
|
+
|
|
17
|
+
#include "liburing.h"
|
|
18
|
+
#include "helpers.h"
|
|
19
|
+
|
|
20
|
+
#define BGID 17
|
|
21
|
+
#define NR_BUFS 4
|
|
22
|
+
#define BR_MASK (NR_BUFS - 1)
|
|
23
|
+
#define BUF_SIZE 32
|
|
24
|
+
|
|
25
|
+
static int do_write(int fd, void *buf, int buf_size)
|
|
26
|
+
{
|
|
27
|
+
int ret;
|
|
28
|
+
|
|
29
|
+
ret = write(fd, buf, buf_size);
|
|
30
|
+
if (ret < 0) {
|
|
31
|
+
perror("write");
|
|
32
|
+
return 0;
|
|
33
|
+
} else if (ret != buf_size) {
|
|
34
|
+
fprintf(stderr, "bad write size %d\n", ret);
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return 1;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static void *thread_fn(void *data)
|
|
42
|
+
{
|
|
43
|
+
char w1[BUF_SIZE], w2[BUF_SIZE];
|
|
44
|
+
int *fds = data;
|
|
45
|
+
|
|
46
|
+
memset(w1, 0x11, BUF_SIZE);
|
|
47
|
+
memset(w2, 0x22, BUF_SIZE);
|
|
48
|
+
|
|
49
|
+
if (!do_write(fds[1], w1, BUF_SIZE))
|
|
50
|
+
return NULL;
|
|
51
|
+
if (!do_write(fds[1], w2, BUF_SIZE))
|
|
52
|
+
return NULL;
|
|
53
|
+
|
|
54
|
+
usleep(100000);
|
|
55
|
+
|
|
56
|
+
if (!do_write(fds[1], w1, BUF_SIZE))
|
|
57
|
+
return NULL;
|
|
58
|
+
if (!do_write(fds[1], w2, BUF_SIZE))
|
|
59
|
+
return NULL;
|
|
60
|
+
|
|
61
|
+
return NULL;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
int main(int argc, char *argv[])
|
|
65
|
+
{
|
|
66
|
+
struct io_uring_buf_ring *br;
|
|
67
|
+
struct io_uring_sqe *sqe;
|
|
68
|
+
struct io_uring_cqe *cqe;
|
|
69
|
+
struct io_uring ring;
|
|
70
|
+
pthread_t thread;
|
|
71
|
+
int i, ret, fds[2];
|
|
72
|
+
void *buf, *tret;
|
|
73
|
+
|
|
74
|
+
if (argc > 1)
|
|
75
|
+
return T_EXIT_SKIP;
|
|
76
|
+
|
|
77
|
+
if (pipe(fds) < 0) {
|
|
78
|
+
perror("pipe");
|
|
79
|
+
return T_EXIT_FAIL;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
ret = io_uring_queue_init(8, &ring, 0);
|
|
83
|
+
if (ret) {
|
|
84
|
+
fprintf(stderr, "queue_init: %d\n", ret);
|
|
85
|
+
return T_EXIT_FAIL;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
br = io_uring_setup_buf_ring(&ring, NR_BUFS, BGID, 0, &ret);
|
|
89
|
+
if (!br) {
|
|
90
|
+
if (ret == -EINVAL)
|
|
91
|
+
return T_EXIT_SKIP;
|
|
92
|
+
fprintf(stderr, "failed buffer ring %d\n", ret);
|
|
93
|
+
return T_EXIT_FAIL;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
buf = malloc(NR_BUFS * BUF_SIZE);
|
|
97
|
+
for (i = 0; i < NR_BUFS; i++) {
|
|
98
|
+
void *this_buf = buf + i * BUF_SIZE;
|
|
99
|
+
|
|
100
|
+
io_uring_buf_ring_add(br, this_buf, BUF_SIZE, i, BR_MASK, i);
|
|
101
|
+
}
|
|
102
|
+
io_uring_buf_ring_advance(br, NR_BUFS);
|
|
103
|
+
|
|
104
|
+
sqe = io_uring_get_sqe(&ring);
|
|
105
|
+
io_uring_prep_read_multishot(sqe, fds[0], 0, 0, BGID);
|
|
106
|
+
|
|
107
|
+
ret = io_uring_submit(&ring);
|
|
108
|
+
if (ret != 1) {
|
|
109
|
+
fprintf(stderr, "bad submit %d\n", ret);
|
|
110
|
+
return T_EXIT_FAIL;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/*
|
|
114
|
+
* read multishot not available would be ready as a cqe when
|
|
115
|
+
* submission returns, check and skip if not.
|
|
116
|
+
*/
|
|
117
|
+
ret = io_uring_peek_cqe(&ring, &cqe);
|
|
118
|
+
if (!ret) {
|
|
119
|
+
if (cqe->res == -EINVAL || cqe->res == -EBADF) {
|
|
120
|
+
free(buf);
|
|
121
|
+
return T_EXIT_SKIP;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
pthread_create(&thread, NULL, thread_fn, fds);
|
|
126
|
+
|
|
127
|
+
for (i = 0; i < 4; i++) {
|
|
128
|
+
int buf_index;
|
|
129
|
+
|
|
130
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
131
|
+
if (ret) {
|
|
132
|
+
fprintf(stderr, "wait %d\n", ret);
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (cqe->res != BUF_SIZE) {
|
|
137
|
+
fprintf(stderr, "size %d\n", cqe->res);
|
|
138
|
+
return T_EXIT_FAIL;
|
|
139
|
+
}
|
|
140
|
+
if (!(cqe->flags & IORING_CQE_F_BUFFER)) {
|
|
141
|
+
fprintf(stderr, "buffer not set\n");
|
|
142
|
+
return T_EXIT_FAIL;
|
|
143
|
+
}
|
|
144
|
+
if (!(cqe->flags & IORING_CQE_F_MORE)) {
|
|
145
|
+
fprintf(stderr, "more not set\n");
|
|
146
|
+
return T_EXIT_FAIL;
|
|
147
|
+
}
|
|
148
|
+
buf_index = cqe->flags >> 16;
|
|
149
|
+
assert(buf_index >= 0 && buf_index <= NR_BUFS);
|
|
150
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
pthread_join(thread, &tret);
|
|
154
|
+
free(buf);
|
|
155
|
+
return T_EXIT_PASS;
|
|
156
|
+
}
|