uringmachine 0.3 → 0.5
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/workflows/test.yml +2 -1
- data/CHANGELOG.md +23 -0
- data/README.md +128 -0
- data/TODO.md +14 -0
- data/examples/bm_snooze.rb +89 -0
- data/examples/bm_write.rb +56 -0
- data/examples/dns_client.rb +12 -0
- data/examples/echo_server.rb +18 -40
- data/examples/http_server.rb +42 -43
- data/examples/inout.rb +19 -0
- data/examples/nc.rb +36 -0
- data/examples/server_client.rb +64 -0
- data/examples/snooze.rb +44 -0
- data/examples/write_dev_null.rb +16 -0
- data/ext/um/extconf.rb +24 -23
- data/ext/um/um.c +524 -278
- data/ext/um/um.h +146 -44
- data/ext/um/um_buffer.c +49 -0
- data/ext/um/um_class.c +217 -106
- data/ext/um/um_const.c +213 -0
- data/ext/um/um_ext.c +4 -0
- data/ext/um/um_mutex_class.c +47 -0
- data/ext/um/um_op.c +86 -114
- data/ext/um/um_queue_class.c +58 -0
- data/ext/um/um_sync.c +273 -0
- data/ext/um/um_utils.c +49 -4
- data/lib/uringmachine/dns_resolver.rb +84 -0
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +28 -0
- data/supressions/ruby.supp +71 -0
- data/test/helper.rb +8 -0
- data/test/test_um.rb +685 -46
- data/vendor/liburing/.github/workflows/build.yml +29 -1
- data/vendor/liburing/.gitignore +6 -0
- data/vendor/liburing/CHANGELOG +16 -0
- data/vendor/liburing/CONTRIBUTING.md +165 -0
- data/vendor/liburing/configure +64 -0
- data/vendor/liburing/examples/Makefile +9 -1
- data/vendor/liburing/examples/kdigest.c +405 -0
- data/vendor/liburing/examples/proxy.c +75 -8
- data/vendor/liburing/examples/reg-wait.c +159 -0
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/Makefile +16 -2
- data/vendor/liburing/src/include/liburing/io_uring.h +77 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
- data/vendor/liburing/src/include/liburing.h +59 -6
- data/vendor/liburing/src/int_flags.h +10 -3
- data/vendor/liburing/src/liburing-ffi.map +16 -0
- data/vendor/liburing/src/liburing.map +10 -0
- data/vendor/liburing/src/queue.c +28 -16
- data/vendor/liburing/src/register.c +106 -1
- data/vendor/liburing/src/sanitize.c +176 -0
- data/vendor/liburing/src/setup.c +47 -19
- data/vendor/liburing/src/setup.h +6 -0
- 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 +38 -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/cmd-discard.c +427 -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/fifo-nonblock-read.c +69 -0
- data/vendor/liburing/test/file-exit-unreg.c +48 -0
- 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 +4 -0
- data/vendor/liburing/test/io_uring_register.c +38 -8
- 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 +16 -3
- data/vendor/liburing/test/no-mmap-inval.c +3 -1
- 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 +158 -153
- data/vendor/liburing/test/read-mshot-stdin.c +121 -0
- data/vendor/liburing/test/read-mshot.c +282 -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 +94 -31
- data/vendor/liburing/test/reg-fd-only.c +15 -5
- data/vendor/liburing/test/reg-wait.c +251 -0
- data/vendor/liburing/test/regbuf-clone.c +645 -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/resize-rings.c +643 -0
- data/vendor/liburing/test/ringbuf-read.c +5 -0
- data/vendor/liburing/test/ringbuf-status.c +5 -1
- data/vendor/liburing/test/rsrc_tags.c +1 -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 +40 -33
- data/vendor/liburing/test/sqwait.c +136 -0
- 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 +56 -22
- data/vendor/liburing/test/thread-exit.c +5 -0
- data/vendor/liburing/test/timeout-new.c +1 -26
- data/vendor/liburing/test/timeout.c +25 -34
- 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 +37 -6
- data/examples/event_loop.rb +0 -69
- data/examples/fibers.rb +0 -105
- data/examples/http_server_multishot.rb +0 -57
- data/examples/http_server_simpler.rb +0 -34
@@ -1,153 +1,158 @@
|
|
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
|
+
io_uring_free_buf_ring(&ring, br, NR_BUFS, BGID);
|
155
|
+
io_uring_queue_exit(&ring);
|
156
|
+
free(buf);
|
157
|
+
return T_EXIT_PASS;
|
158
|
+
}
|
@@ -0,0 +1,121 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: test multishot read on stdin. Not that this REQUIRES input
|
4
|
+
* to be received on stdin, and hence if invoked with no
|
5
|
+
* arguments, or without the single argument being 'stdin',
|
6
|
+
* the test will just return SKIPPED. Can't be run from the
|
7
|
+
* standard test harness, as it's interactive.
|
8
|
+
*
|
9
|
+
* To run, do run "test/read-mshot-stdin.t stdin" and then input text on
|
10
|
+
* the console, followed by enter / line feed. If it works as it should,
|
11
|
+
* it'll output the received CQE data. If an error is detected, it'll
|
12
|
+
* abort with an error.
|
13
|
+
*/
|
14
|
+
#include <errno.h>
|
15
|
+
#include <stdio.h>
|
16
|
+
#include <unistd.h>
|
17
|
+
#include <stdlib.h>
|
18
|
+
#include <string.h>
|
19
|
+
#include <fcntl.h>
|
20
|
+
#include <sys/stat.h>
|
21
|
+
|
22
|
+
#include "liburing.h"
|
23
|
+
#include "helpers.h"
|
24
|
+
|
25
|
+
#define BUF_SIZE 32
|
26
|
+
#define NR_BUFS 64
|
27
|
+
#define BUF_BGID 1
|
28
|
+
|
29
|
+
#define BR_MASK (NR_BUFS - 1)
|
30
|
+
|
31
|
+
static int test_stdin(void)
|
32
|
+
{
|
33
|
+
struct io_uring_buf_ring *br;
|
34
|
+
struct io_uring_params p = { };
|
35
|
+
struct io_uring_sqe *sqe;
|
36
|
+
struct io_uring_cqe *cqe;
|
37
|
+
struct io_uring ring;
|
38
|
+
int ret, i, last_bid;
|
39
|
+
char *buf, *ptr;
|
40
|
+
|
41
|
+
p.flags = IORING_SETUP_CQSIZE;
|
42
|
+
p.cq_entries = NR_BUFS;
|
43
|
+
ret = io_uring_queue_init_params(1, &ring, &p);
|
44
|
+
if (ret) {
|
45
|
+
if (ret == -EINVAL)
|
46
|
+
return T_EXIT_SKIP;
|
47
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
48
|
+
return T_EXIT_FAIL;
|
49
|
+
}
|
50
|
+
|
51
|
+
if (posix_memalign((void **) &buf, 4096, NR_BUFS * BUF_SIZE))
|
52
|
+
return T_EXIT_FAIL;
|
53
|
+
|
54
|
+
br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID, 0, &ret);
|
55
|
+
if (!br) {
|
56
|
+
if (ret == -EINVAL)
|
57
|
+
return T_EXIT_SKIP;
|
58
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
59
|
+
return T_EXIT_FAIL;
|
60
|
+
}
|
61
|
+
|
62
|
+
ptr = buf;
|
63
|
+
for (i = 0; i < NR_BUFS; i++) {
|
64
|
+
io_uring_buf_ring_add(br, ptr, BUF_SIZE, i + 1, BR_MASK, i);
|
65
|
+
ptr += BUF_SIZE;
|
66
|
+
}
|
67
|
+
io_uring_buf_ring_advance(br, NR_BUFS);
|
68
|
+
|
69
|
+
sqe = io_uring_get_sqe(&ring);
|
70
|
+
io_uring_prep_read_multishot(sqe, STDIN_FILENO, 0, 0, BUF_BGID);
|
71
|
+
|
72
|
+
ret = io_uring_submit(&ring);
|
73
|
+
if (ret != 1) {
|
74
|
+
fprintf(stderr, "submit: %d\n", ret);
|
75
|
+
return T_EXIT_FAIL;
|
76
|
+
}
|
77
|
+
|
78
|
+
last_bid = -1;
|
79
|
+
do {
|
80
|
+
int bid;
|
81
|
+
|
82
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
83
|
+
if (ret) {
|
84
|
+
fprintf(stderr, "wait cqe failed %d\n", ret);
|
85
|
+
return T_EXIT_FAIL;
|
86
|
+
}
|
87
|
+
if (cqe->res && !(cqe->flags & IORING_CQE_F_BUFFER)) {
|
88
|
+
fprintf(stderr, "BUF flag not set %x\n", cqe->flags);
|
89
|
+
return T_EXIT_FAIL;
|
90
|
+
}
|
91
|
+
bid = cqe->flags >> 16;
|
92
|
+
printf("CQE res %d, bid %d, flags %x\n", cqe->res, bid, cqe->flags);
|
93
|
+
if (cqe->res > 0 && last_bid != -1 && last_bid + 1 != bid) {
|
94
|
+
fprintf(stderr, "Got bid %d, wanted %d\n", bid, last_bid + 1);
|
95
|
+
return T_EXIT_FAIL;
|
96
|
+
}
|
97
|
+
if (!(cqe->flags & IORING_CQE_F_MORE)) {
|
98
|
+
io_uring_cqe_seen(&ring, cqe);
|
99
|
+
break;
|
100
|
+
}
|
101
|
+
|
102
|
+
last_bid = bid;
|
103
|
+
io_uring_cqe_seen(&ring, cqe);
|
104
|
+
}while (1);
|
105
|
+
|
106
|
+
io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
|
107
|
+
io_uring_queue_exit(&ring);
|
108
|
+
free(buf);
|
109
|
+
return T_EXIT_PASS;
|
110
|
+
}
|
111
|
+
|
112
|
+
int main(int argc, char *argv[])
|
113
|
+
{
|
114
|
+
if (argc == 1)
|
115
|
+
return T_EXIT_SKIP;
|
116
|
+
else if (argc > 2)
|
117
|
+
return T_EXIT_SKIP;
|
118
|
+
if (!strcmp(argv[1], "stdin"))
|
119
|
+
return test_stdin();
|
120
|
+
return T_EXIT_SKIP;
|
121
|
+
}
|