polyphony 0.98 → 0.99.1
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 +1 -1
- data/.rubocop.yml +3 -3
- data/.yardopts +30 -0
- data/CHANGELOG.md +11 -0
- data/LICENSE +1 -1
- data/README.md +63 -29
- data/Rakefile +1 -5
- data/TODO.md +0 -4
- data/docs/{main-concepts/concurrency.md → concurrency.md} +2 -9
- data/docs/{main-concepts/design-principles.md → design-principles.md} +3 -9
- data/docs/{main-concepts/exception-handling.md → exception-handling.md} +2 -9
- data/docs/{main-concepts/extending.md → extending.md} +2 -9
- data/docs/faq.md +3 -16
- data/docs/{main-concepts/fiber-scheduling.md → fiber-scheduling.md} +1 -9
- data/docs/link_rewriter.rb +16 -0
- data/docs/{getting-started/overview.md → overview.md} +1 -30
- data/docs/{getting-started/tutorial.md → tutorial.md} +3 -28
- data/docs/{_posts/2020-07-26-polyphony-0.44.md → whats-new.md} +3 -1
- data/examples/adapters/redis_client.rb +3 -2
- data/examples/io/echo_server.rb +1 -1
- data/examples/io/echo_server_plain_ruby.rb +26 -0
- data/examples/io/https_server_sni_2.rb +14 -8
- data/ext/polyphony/backend_io_uring.c +154 -9
- data/ext/polyphony/backend_io_uring_context.c +21 -12
- data/ext/polyphony/backend_io_uring_context.h +12 -7
- data/ext/polyphony/backend_libev.c +1 -1
- data/ext/polyphony/extconf.rb +25 -8
- data/ext/polyphony/fiber.c +79 -2
- data/ext/polyphony/io_extensions.c +53 -0
- data/ext/polyphony/libev.h +0 -2
- data/ext/polyphony/pipe.c +42 -2
- data/ext/polyphony/polyphony.c +345 -31
- data/ext/polyphony/polyphony.h +9 -2
- data/ext/polyphony/queue.c +181 -0
- data/ext/polyphony/ring_buffer.c +0 -1
- data/ext/polyphony/runqueue.c +8 -1
- data/ext/polyphony/runqueue_ring_buffer.c +13 -0
- data/ext/polyphony/runqueue_ring_buffer.h +2 -1
- data/ext/polyphony/socket_extensions.c +6 -0
- data/ext/polyphony/thread.c +34 -2
- data/lib/polyphony/adapters/process.rb +11 -1
- data/lib/polyphony/adapters/sequel.rb +1 -1
- data/lib/polyphony/core/channel.rb +2 -0
- data/lib/polyphony/core/debug.rb +1 -1
- data/lib/polyphony/core/global_api.rb +25 -24
- data/lib/polyphony/core/resource_pool.rb +7 -6
- data/lib/polyphony/core/sync.rb +55 -2
- data/lib/polyphony/core/thread_pool.rb +3 -3
- data/lib/polyphony/core/timer.rb +8 -8
- data/lib/polyphony/extensions/exception.rb +2 -0
- data/lib/polyphony/extensions/fiber.rb +15 -13
- data/lib/polyphony/extensions/io.rb +161 -16
- data/lib/polyphony/extensions/kernel.rb +20 -2
- data/lib/polyphony/extensions/openssl.rb +101 -12
- data/lib/polyphony/extensions/pipe.rb +103 -7
- data/lib/polyphony/extensions/process.rb +13 -1
- data/lib/polyphony/extensions/socket.rb +93 -27
- data/lib/polyphony/extensions/thread.rb +9 -1
- data/lib/polyphony/extensions/timeout.rb +1 -1
- data/lib/polyphony/version.rb +2 -1
- data/lib/polyphony.rb +27 -7
- data/polyphony.gemspec +1 -8
- data/test/stress.rb +1 -1
- data/test/test_global_api.rb +45 -7
- data/test/test_io.rb +6 -7
- data/test/test_socket.rb +157 -0
- data/test/test_sync.rb +42 -1
- data/test/test_timer.rb +5 -5
- data/vendor/liburing/.github/workflows/build.yml +7 -16
- data/vendor/liburing/.gitignore +5 -0
- data/vendor/liburing/CHANGELOG +23 -1
- data/vendor/liburing/Makefile +4 -3
- data/vendor/liburing/Makefile.common +1 -0
- data/vendor/liburing/README +48 -0
- data/vendor/liburing/configure +76 -6
- data/vendor/liburing/debian/changelog +11 -0
- data/vendor/liburing/debian/control +7 -16
- data/vendor/liburing/debian/liburing-dev.manpages +3 -6
- data/vendor/liburing/debian/liburing2.install +1 -0
- data/vendor/liburing/debian/liburing2.symbols +56 -0
- data/vendor/liburing/debian/rules +15 -68
- data/vendor/liburing/examples/Makefile +4 -0
- data/vendor/liburing/examples/io_uring-close-test.c +123 -0
- data/vendor/liburing/examples/io_uring-udp.c +1 -1
- data/vendor/liburing/examples/send-zerocopy.c +315 -56
- data/vendor/liburing/examples/ucontext-cp.c +2 -17
- data/vendor/liburing/liburing-ffi.pc.in +12 -0
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/make-debs.sh +3 -3
- data/vendor/liburing/man/IO_URING_CHECK_VERSION.3 +1 -0
- data/vendor/liburing/man/IO_URING_VERSION_MAJOR.3 +1 -0
- data/vendor/liburing/man/IO_URING_VERSION_MINOR.3 +1 -0
- data/vendor/liburing/man/io_uring_buf_ring_add.3 +6 -6
- data/vendor/liburing/man/io_uring_check_version.3 +72 -0
- data/vendor/liburing/man/io_uring_close_ring_fd.3 +43 -0
- data/vendor/liburing/man/io_uring_major_version.3 +1 -0
- data/vendor/liburing/man/io_uring_minor_version.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_accept.3 +1 -1
- data/vendor/liburing/man/io_uring_prep_fgetxattr.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_fsetxattr.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_getxattr.3 +61 -0
- data/vendor/liburing/man/io_uring_prep_link_timeout.3 +94 -0
- data/vendor/liburing/man/io_uring_prep_msg_ring.3 +22 -2
- data/vendor/liburing/man/io_uring_prep_msg_ring_cqe_flags.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_poll_add.3 +1 -1
- data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +18 -9
- data/vendor/liburing/man/io_uring_prep_readv.3 +3 -3
- data/vendor/liburing/man/io_uring_prep_readv2.3 +3 -3
- data/vendor/liburing/man/io_uring_prep_recv.3 +5 -5
- data/vendor/liburing/man/io_uring_prep_recvmsg.3 +4 -4
- data/vendor/liburing/man/io_uring_prep_send.3 +9 -0
- data/vendor/liburing/man/io_uring_prep_send_set_addr.3 +38 -0
- data/vendor/liburing/man/io_uring_prep_send_zc.3 +39 -7
- data/vendor/liburing/man/io_uring_prep_send_zc_fixed.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_sendmsg.3 +20 -0
- data/vendor/liburing/man/io_uring_prep_sendmsg_zc.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_setxattr.3 +64 -0
- data/vendor/liburing/man/io_uring_prep_splice.3 +40 -0
- data/vendor/liburing/man/io_uring_prep_writev.3 +2 -2
- data/vendor/liburing/man/io_uring_prep_writev2.3 +2 -2
- data/vendor/liburing/man/io_uring_recvmsg_out.3 +13 -9
- data/vendor/liburing/man/io_uring_register.2 +15 -9
- data/vendor/liburing/man/io_uring_register_buf_ring.3 +4 -4
- data/vendor/liburing/man/io_uring_register_buffers.3 +49 -6
- data/vendor/liburing/man/io_uring_register_buffers_sparse.3 +1 -0
- data/vendor/liburing/man/io_uring_register_buffers_tags.3 +1 -0
- data/vendor/liburing/man/io_uring_register_buffers_update_tag.3 +1 -0
- data/vendor/liburing/man/io_uring_register_files.3 +60 -5
- data/vendor/liburing/man/io_uring_register_files_tags.3 +1 -0
- data/vendor/liburing/man/io_uring_register_files_update.3 +1 -0
- data/vendor/liburing/man/io_uring_register_files_update_tag.3 +1 -0
- data/vendor/liburing/man/io_uring_setup.2 +31 -2
- data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +1 -1
- data/vendor/liburing/src/Makefile +25 -3
- data/vendor/liburing/src/ffi.c +15 -0
- data/vendor/liburing/src/include/liburing/io_uring.h +30 -7
- data/vendor/liburing/src/include/liburing.h +190 -148
- data/vendor/liburing/src/int_flags.h +1 -0
- data/vendor/liburing/src/lib.h +5 -16
- data/vendor/liburing/src/liburing-ffi.map +172 -0
- data/vendor/liburing/src/liburing.map +11 -0
- data/vendor/liburing/src/nolibc.c +9 -2
- data/vendor/liburing/src/queue.c +2 -2
- data/vendor/liburing/src/register.c +66 -96
- data/vendor/liburing/src/setup.c +5 -4
- data/vendor/liburing/src/version.c +21 -0
- data/vendor/liburing/test/232c93d07b74.c +3 -3
- data/vendor/liburing/test/35fa71a030ca.c +3 -3
- data/vendor/liburing/test/500f9fbadef8.c +2 -0
- data/vendor/liburing/test/917257daa0fe.c +1 -1
- data/vendor/liburing/test/Makefile +27 -7
- data/vendor/liburing/test/a0908ae19763.c +2 -2
- data/vendor/liburing/test/a4c0b3decb33.c +2 -2
- data/vendor/liburing/test/accept-link.c +4 -4
- data/vendor/liburing/test/accept-reuse.c +5 -7
- data/vendor/liburing/test/accept.c +34 -31
- data/vendor/liburing/test/b19062a56726.c +1 -1
- data/vendor/liburing/test/buf-ring.c +58 -4
- data/vendor/liburing/test/ce593a6c480a.c +2 -2
- data/vendor/liburing/test/close-opath.c +2 -1
- data/vendor/liburing/test/connect.c +8 -0
- data/vendor/liburing/test/cq-overflow.c +14 -8
- data/vendor/liburing/test/d4ae271dfaae.c +1 -1
- data/vendor/liburing/test/defer-taskrun.c +64 -9
- data/vendor/liburing/test/defer.c +1 -1
- data/vendor/liburing/test/double-poll-crash.c +3 -3
- data/vendor/liburing/test/eeed8b54e0df.c +8 -3
- data/vendor/liburing/test/eploop.c +74 -0
- data/vendor/liburing/test/eventfd-ring.c +1 -1
- data/vendor/liburing/test/eventfd.c +1 -1
- data/vendor/liburing/test/evloop.c +73 -0
- data/vendor/liburing/test/exit-no-cleanup.c +1 -1
- data/vendor/liburing/test/fadvise.c +1 -1
- data/vendor/liburing/test/fc2a85cb02ef.c +3 -3
- data/vendor/liburing/test/fd-pass.c +35 -16
- data/vendor/liburing/test/file-register.c +61 -0
- data/vendor/liburing/test/file-verify.c +2 -2
- data/vendor/liburing/test/files-exit-hang-timeout.c +2 -2
- data/vendor/liburing/test/fixed-link.c +1 -1
- data/vendor/liburing/test/fsnotify.c +118 -0
- data/vendor/liburing/test/hardlink.c +1 -1
- data/vendor/liburing/test/helpers.c +54 -2
- data/vendor/liburing/test/helpers.h +4 -0
- data/vendor/liburing/test/io-cancel.c +3 -1
- data/vendor/liburing/test/io_uring_passthrough.c +39 -8
- data/vendor/liburing/test/io_uring_setup.c +3 -80
- data/vendor/liburing/test/iopoll-overflow.c +118 -0
- data/vendor/liburing/test/iopoll.c +90 -4
- data/vendor/liburing/test/lfs-openat-write.c +7 -9
- data/vendor/liburing/test/lfs-openat.c +6 -8
- data/vendor/liburing/test/link_drain.c +31 -5
- data/vendor/liburing/test/madvise.c +1 -1
- data/vendor/liburing/test/msg-ring-flags.c +192 -0
- data/vendor/liburing/test/msg-ring-overflow.c +159 -0
- data/vendor/liburing/test/msg-ring.c +173 -13
- data/vendor/liburing/test/multicqes_drain.c +22 -19
- data/vendor/liburing/test/nvme.h +4 -3
- data/vendor/liburing/test/pipe-bug.c +95 -0
- data/vendor/liburing/test/poll-link.c +3 -3
- data/vendor/liburing/test/poll-many.c +41 -19
- data/vendor/liburing/test/poll-mshot-overflow.c +105 -2
- data/vendor/liburing/test/poll-race-mshot.c +292 -0
- data/vendor/liburing/test/poll-race.c +105 -0
- data/vendor/liburing/test/poll.c +244 -26
- data/vendor/liburing/test/pollfree.c +5 -5
- data/vendor/liburing/test/read-before-exit.c +20 -3
- data/vendor/liburing/test/read-write.c +2 -0
- data/vendor/liburing/test/recv-multishot.c +96 -3
- data/vendor/liburing/test/reg-reg-ring.c +90 -0
- data/vendor/liburing/test/rename.c +1 -1
- data/vendor/liburing/test/ring-leak.c +0 -1
- data/vendor/liburing/test/ring-leak2.c +1 -1
- data/vendor/liburing/test/ringbuf-read.c +10 -6
- data/vendor/liburing/test/send-zerocopy.c +273 -103
- data/vendor/liburing/test/send_recv.c +7 -4
- data/vendor/liburing/test/sendmsg_fs_cve.c +2 -2
- data/vendor/liburing/test/single-issuer.c +7 -9
- data/vendor/liburing/test/skip-cqe.c +3 -4
- data/vendor/liburing/test/socket.c +0 -1
- data/vendor/liburing/test/sq-poll-dup.c +10 -3
- data/vendor/liburing/test/sq-poll-kthread.c +1 -1
- data/vendor/liburing/test/sq-poll-share.c +3 -2
- data/vendor/liburing/test/sqpoll-cancel-hang.c +17 -6
- data/vendor/liburing/test/sqpoll-disable-exit.c +4 -4
- data/vendor/liburing/test/symlink.c +2 -1
- data/vendor/liburing/test/test.h +2 -1
- data/vendor/liburing/test/timeout-new.c +11 -7
- data/vendor/liburing/test/timeout.c +1 -2
- data/vendor/liburing/test/unlink.c +1 -1
- data/vendor/liburing/test/version.c +25 -0
- data/vendor/liburing/test/wakeup-hang.c +1 -1
- data/vendor/liburing/test/xattr.c +8 -4
- metadata +57 -44
- data/docs/_config.yml +0 -64
- data/docs/_includes/head.html +0 -40
- data/docs/_includes/title.html +0 -1
- data/docs/_sass/custom/custom.scss +0 -10
- data/docs/_sass/overrides.scss +0 -0
- data/docs/api-reference/exception.md +0 -31
- data/docs/api-reference/fiber.md +0 -425
- data/docs/api-reference/index.md +0 -9
- data/docs/api-reference/io.md +0 -36
- data/docs/api-reference/object.md +0 -99
- data/docs/api-reference/polyphony-baseexception.md +0 -33
- data/docs/api-reference/polyphony-cancel.md +0 -26
- data/docs/api-reference/polyphony-moveon.md +0 -24
- data/docs/api-reference/polyphony-net.md +0 -20
- data/docs/api-reference/polyphony-process.md +0 -28
- data/docs/api-reference/polyphony-resourcepool.md +0 -59
- data/docs/api-reference/polyphony-restart.md +0 -18
- data/docs/api-reference/polyphony-terminate.md +0 -18
- data/docs/api-reference/polyphony-threadpool.md +0 -67
- data/docs/api-reference/polyphony-throttler.md +0 -77
- data/docs/api-reference/polyphony.md +0 -36
- data/docs/api-reference/thread.md +0 -88
- data/docs/favicon.ico +0 -0
- data/docs/getting-started/index.md +0 -10
- data/docs/getting-started/installing.md +0 -34
- data/vendor/liburing/debian/compat +0 -1
- data/vendor/liburing/debian/liburing1-udeb.install +0 -1
- data/vendor/liburing/debian/liburing1.install +0 -1
- data/vendor/liburing/debian/liburing1.symbols +0 -32
- /data/{docs/assets/img → assets}/echo-fibers.svg +0 -0
- /data/{docs → assets}/polyphony-logo.png +0 -0
- /data/{docs/assets/img → assets}/sleeping-fiber.svg +0 -0
|
@@ -87,6 +87,8 @@ static int __test_io(const char *file, struct io_uring *ring, int write, int sqt
|
|
|
87
87
|
}
|
|
88
88
|
fd = open(file, open_flags);
|
|
89
89
|
if (fd < 0) {
|
|
90
|
+
if (errno == EINVAL)
|
|
91
|
+
return 0;
|
|
90
92
|
perror("file open");
|
|
91
93
|
goto err;
|
|
92
94
|
}
|
|
@@ -201,7 +203,80 @@ err:
|
|
|
201
203
|
return 1;
|
|
202
204
|
}
|
|
203
205
|
|
|
204
|
-
|
|
206
|
+
static void sig_alrm(int sig)
|
|
207
|
+
{
|
|
208
|
+
fprintf(stderr, "Ran out of time for peek test!\n");
|
|
209
|
+
exit(T_EXIT_FAIL);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/*
|
|
213
|
+
* if we are polling, io_uring_cqe_peek() always needs to enter the kernel
|
|
214
|
+
*/
|
|
215
|
+
static int test_io_uring_cqe_peek(const char *file)
|
|
216
|
+
{
|
|
217
|
+
struct io_uring_cqe *cqe;
|
|
218
|
+
struct io_uring ring;
|
|
219
|
+
struct sigaction act;
|
|
220
|
+
int fd, i, ret = T_EXIT_FAIL;
|
|
221
|
+
|
|
222
|
+
if (no_iopoll)
|
|
223
|
+
return 0;
|
|
224
|
+
|
|
225
|
+
ret = io_uring_queue_init(64, &ring, IORING_SETUP_IOPOLL);
|
|
226
|
+
if (ret) {
|
|
227
|
+
fprintf(stderr, "ring create failed: %d\n", ret);
|
|
228
|
+
return 1;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
fd = open(file, O_RDONLY | O_DIRECT);
|
|
232
|
+
if (fd < 0) {
|
|
233
|
+
if (errno == EINVAL) {
|
|
234
|
+
io_uring_queue_exit(&ring);
|
|
235
|
+
return T_EXIT_SKIP;
|
|
236
|
+
}
|
|
237
|
+
perror("file open");
|
|
238
|
+
goto err;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
for (i = 0; i < BUFFERS; i++) {
|
|
242
|
+
struct io_uring_sqe *sqe;
|
|
243
|
+
off_t offset = BS * (rand() % BUFFERS);
|
|
244
|
+
|
|
245
|
+
sqe = io_uring_get_sqe(&ring);
|
|
246
|
+
io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
|
|
247
|
+
sqe->user_data = 1;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/*
|
|
251
|
+
* Set alarm for 5 seconds, we should be done way before that
|
|
252
|
+
*/
|
|
253
|
+
memset(&act, 0, sizeof(act));
|
|
254
|
+
act.sa_handler = sig_alrm;
|
|
255
|
+
sigaction(SIGALRM, &act, NULL);
|
|
256
|
+
alarm(5);
|
|
257
|
+
|
|
258
|
+
ret = io_uring_submit(&ring);
|
|
259
|
+
if (ret != BUFFERS) {
|
|
260
|
+
fprintf(stderr, "submit=%d\n", ret);
|
|
261
|
+
goto err;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
ret = T_EXIT_PASS;
|
|
265
|
+
i = 0;
|
|
266
|
+
do {
|
|
267
|
+
ret = io_uring_peek_cqe(&ring, &cqe);
|
|
268
|
+
if (ret)
|
|
269
|
+
continue;
|
|
270
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
271
|
+
i++;
|
|
272
|
+
} while (i < BUFFERS);
|
|
273
|
+
|
|
274
|
+
err:
|
|
275
|
+
if (fd != -1)
|
|
276
|
+
close(fd);
|
|
277
|
+
io_uring_queue_exit(&ring);
|
|
278
|
+
return ret;
|
|
279
|
+
}
|
|
205
280
|
|
|
206
281
|
/*
|
|
207
282
|
* if we are polling io_uring_submit needs to always enter the
|
|
@@ -227,6 +302,8 @@ static int test_io_uring_submit_enters(const char *file)
|
|
|
227
302
|
open_flags = O_WRONLY | O_DIRECT;
|
|
228
303
|
fd = open(file, open_flags);
|
|
229
304
|
if (fd < 0) {
|
|
305
|
+
if (errno == EINVAL)
|
|
306
|
+
return T_EXIT_SKIP;
|
|
230
307
|
perror("file open");
|
|
231
308
|
goto err;
|
|
232
309
|
}
|
|
@@ -364,9 +441,18 @@ int main(int argc, char *argv[])
|
|
|
364
441
|
}
|
|
365
442
|
|
|
366
443
|
ret = test_io_uring_submit_enters(fname);
|
|
367
|
-
if (ret) {
|
|
368
|
-
|
|
369
|
-
|
|
444
|
+
if (ret == T_EXIT_FAIL) {
|
|
445
|
+
fprintf(stderr, "test_io_uring_submit_enters failed\n");
|
|
446
|
+
goto err;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/*
|
|
450
|
+
* Keep this last, it exits on failure
|
|
451
|
+
*/
|
|
452
|
+
ret = test_io_uring_cqe_peek(fname);
|
|
453
|
+
if (ret == T_EXIT_FAIL) {
|
|
454
|
+
fprintf(stderr, "test_io_uring_cqe_peek failed\n");
|
|
455
|
+
goto err;
|
|
370
456
|
}
|
|
371
457
|
|
|
372
458
|
if (fname != argv[1])
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
/* SPDX-License-Identifier: MIT */
|
|
2
2
|
|
|
3
|
-
#define _LARGEFILE_SOURCE
|
|
4
|
-
#define _FILE_OFFSET_BITS 64
|
|
5
|
-
|
|
6
|
-
#include <liburing.h>
|
|
7
3
|
#include <string.h>
|
|
8
4
|
#include <stdio.h>
|
|
9
5
|
#include <stdlib.h>
|
|
@@ -14,16 +10,18 @@
|
|
|
14
10
|
#include <sys/resource.h>
|
|
15
11
|
#include <unistd.h>
|
|
16
12
|
|
|
13
|
+
#include "liburing.h"
|
|
17
14
|
#include "helpers.h"
|
|
18
15
|
|
|
19
16
|
static const int RSIZE = 2;
|
|
20
|
-
static const int OPEN_FLAGS = O_RDWR | O_CREAT;
|
|
17
|
+
static const int OPEN_FLAGS = O_RDWR | O_CREAT | O_LARGEFILE;
|
|
21
18
|
static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR;
|
|
22
19
|
|
|
23
|
-
#define DIE(...)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
#define DIE(...) \
|
|
21
|
+
do { \
|
|
22
|
+
fprintf(stderr, __VA_ARGS__); \
|
|
23
|
+
abort(); \
|
|
24
|
+
} while(0)
|
|
27
25
|
|
|
28
26
|
static int do_write(struct io_uring *ring, int fd, off_t offset)
|
|
29
27
|
{
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
/* SPDX-License-Identifier: MIT */
|
|
2
2
|
|
|
3
|
-
#define _LARGEFILE_SOURCE
|
|
4
|
-
#define _FILE_OFFSET_BITS 64
|
|
5
|
-
|
|
6
3
|
#include <string.h>
|
|
7
4
|
#include <stdio.h>
|
|
8
5
|
#include <stdlib.h>
|
|
@@ -15,13 +12,14 @@
|
|
|
15
12
|
|
|
16
13
|
#include "liburing.h"
|
|
17
14
|
|
|
18
|
-
#define DIE(...)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
#define DIE(...) \
|
|
16
|
+
do { \
|
|
17
|
+
fprintf(stderr, __VA_ARGS__); \
|
|
18
|
+
abort(); \
|
|
19
|
+
} while(0)
|
|
22
20
|
|
|
23
21
|
static const int RSIZE = 2;
|
|
24
|
-
static const int OPEN_FLAGS = O_RDWR | O_CREAT;
|
|
22
|
+
static const int OPEN_FLAGS = O_RDWR | O_CREAT | O_LARGEFILE;
|
|
25
23
|
static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR;
|
|
26
24
|
|
|
27
25
|
static int open_io_uring(struct io_uring *ring, int dfd, const char *fn)
|
|
@@ -96,7 +96,7 @@ err:
|
|
|
96
96
|
return 1;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
int test_link_drain_multi(struct io_uring *ring)
|
|
99
|
+
static int test_link_drain_multi(struct io_uring *ring)
|
|
100
100
|
{
|
|
101
101
|
struct io_uring_cqe *cqe;
|
|
102
102
|
struct io_uring_sqe *sqe[9];
|
|
@@ -198,15 +198,17 @@ err:
|
|
|
198
198
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
int
|
|
201
|
+
static int test_drain(bool defer)
|
|
202
202
|
{
|
|
203
203
|
struct io_uring ring;
|
|
204
204
|
int i, ret;
|
|
205
|
+
unsigned int flags = 0;
|
|
205
206
|
|
|
206
|
-
if (
|
|
207
|
-
|
|
207
|
+
if (defer)
|
|
208
|
+
flags = IORING_SETUP_SINGLE_ISSUER |
|
|
209
|
+
IORING_SETUP_DEFER_TASKRUN;
|
|
208
210
|
|
|
209
|
-
ret = io_uring_queue_init(100, &ring,
|
|
211
|
+
ret = io_uring_queue_init(100, &ring, flags);
|
|
210
212
|
if (ret) {
|
|
211
213
|
printf("ring setup failed\n");
|
|
212
214
|
return 1;
|
|
@@ -227,3 +229,27 @@ int main(int argc, char *argv[])
|
|
|
227
229
|
|
|
228
230
|
return ret;
|
|
229
231
|
}
|
|
232
|
+
|
|
233
|
+
int main(int argc, char *argv[])
|
|
234
|
+
{
|
|
235
|
+
int ret;
|
|
236
|
+
|
|
237
|
+
if (argc > 1)
|
|
238
|
+
return T_EXIT_SKIP;
|
|
239
|
+
|
|
240
|
+
ret = test_drain(false);
|
|
241
|
+
if (ret) {
|
|
242
|
+
fprintf(stderr, "test_drain(false) failed\n");
|
|
243
|
+
return T_EXIT_FAIL;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (t_probe_defer_taskrun()) {
|
|
247
|
+
ret = test_drain(true);
|
|
248
|
+
if (ret) {
|
|
249
|
+
fprintf(stderr, "test_drain(true) failed\n");
|
|
250
|
+
return T_EXIT_FAIL;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return T_EXIT_PASS;
|
|
255
|
+
}
|
|
@@ -182,7 +182,7 @@ int main(int argc, char *argv[])
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
/* too hard to reliably test, just ignore */
|
|
185
|
-
if (0 && bad > good)
|
|
185
|
+
if ((0) && bad > good)
|
|
186
186
|
fprintf(stderr, "Suspicious timings (%u > %u)\n", bad, good);
|
|
187
187
|
if (fname != argv[1])
|
|
188
188
|
unlink(fname);
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: test ring messaging with flags command
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
#include <errno.h>
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <unistd.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include <string.h>
|
|
11
|
+
#include <fcntl.h>
|
|
12
|
+
#include <pthread.h>
|
|
13
|
+
|
|
14
|
+
#include "liburing.h"
|
|
15
|
+
#include "helpers.h"
|
|
16
|
+
|
|
17
|
+
#define CUSTOM_FLAG 0x42
|
|
18
|
+
#define USER_DATA 0x5aa5
|
|
19
|
+
#define LEN 0x20
|
|
20
|
+
#define ID 0x1
|
|
21
|
+
|
|
22
|
+
struct data {
|
|
23
|
+
pthread_barrier_t barrier;
|
|
24
|
+
int fd;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
static int recv_msg(struct io_uring *ring)
|
|
28
|
+
{
|
|
29
|
+
struct io_uring_cqe *cqe;
|
|
30
|
+
int ret;
|
|
31
|
+
|
|
32
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
|
33
|
+
if (ret) {
|
|
34
|
+
fprintf(stderr, "wait cqe %d\n", ret);
|
|
35
|
+
return T_EXIT_FAIL;
|
|
36
|
+
}
|
|
37
|
+
if (cqe->user_data != USER_DATA) {
|
|
38
|
+
fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
|
|
39
|
+
return T_EXIT_FAIL;
|
|
40
|
+
}
|
|
41
|
+
if (cqe->res != LEN) {
|
|
42
|
+
fprintf(stderr, "len %x\n", cqe->res);
|
|
43
|
+
return T_EXIT_FAIL;
|
|
44
|
+
}
|
|
45
|
+
if (cqe->flags != CUSTOM_FLAG) {
|
|
46
|
+
fprintf(stderr, "flags %x\n", cqe->flags);
|
|
47
|
+
return T_EXIT_FAIL;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return T_EXIT_PASS;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static int send_msg(struct io_uring *ring, int target_fd)
|
|
54
|
+
{
|
|
55
|
+
struct io_uring_cqe *cqe;
|
|
56
|
+
struct io_uring_sqe *sqe;
|
|
57
|
+
int ret;
|
|
58
|
+
|
|
59
|
+
sqe = io_uring_get_sqe(ring);
|
|
60
|
+
if (!sqe) {
|
|
61
|
+
fprintf(stderr, "get sqe failed\n");
|
|
62
|
+
return T_EXIT_FAIL;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
io_uring_prep_msg_ring_cqe_flags(sqe, target_fd, LEN, USER_DATA,
|
|
66
|
+
0, CUSTOM_FLAG);
|
|
67
|
+
sqe->user_data = ID;
|
|
68
|
+
|
|
69
|
+
ret = io_uring_submit(ring);
|
|
70
|
+
if (ret <= 0) {
|
|
71
|
+
if (ret == -EINVAL)
|
|
72
|
+
return T_EXIT_SKIP;
|
|
73
|
+
|
|
74
|
+
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
|
75
|
+
return T_EXIT_FAIL;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
|
79
|
+
if (ret < 0) {
|
|
80
|
+
fprintf(stderr, "wait completion %d\n", ret);
|
|
81
|
+
return T_EXIT_FAIL;
|
|
82
|
+
}
|
|
83
|
+
if (cqe->res != 0) {
|
|
84
|
+
if (cqe->res == -EINVAL)
|
|
85
|
+
return T_EXIT_SKIP;
|
|
86
|
+
fprintf(stderr, "cqe res %d\n", cqe->res);
|
|
87
|
+
return T_EXIT_FAIL;
|
|
88
|
+
}
|
|
89
|
+
if (cqe->user_data != ID) {
|
|
90
|
+
fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
|
|
91
|
+
return T_EXIT_FAIL;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
io_uring_cqe_seen(ring, cqe);
|
|
95
|
+
return T_EXIT_PASS;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static void *thread_fn(void *data)
|
|
99
|
+
{
|
|
100
|
+
struct data *d = data;
|
|
101
|
+
struct io_uring ring;
|
|
102
|
+
int ret;
|
|
103
|
+
|
|
104
|
+
ret = io_uring_queue_init(2, &ring, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER);
|
|
105
|
+
if (ret) {
|
|
106
|
+
fprintf(stderr, "ring init failed %d\n", ret);
|
|
107
|
+
pthread_barrier_wait(&d->barrier);
|
|
108
|
+
return NULL;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
d->fd = ring.ring_fd;
|
|
112
|
+
pthread_barrier_wait(&d->barrier);
|
|
113
|
+
|
|
114
|
+
if (recv_msg(&ring))
|
|
115
|
+
return (void *) 1;
|
|
116
|
+
|
|
117
|
+
return NULL;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
int main(int argc, char *argv[])
|
|
121
|
+
{
|
|
122
|
+
struct io_uring ring, ring2;
|
|
123
|
+
pthread_t thread;
|
|
124
|
+
struct data d;
|
|
125
|
+
void *ret2;
|
|
126
|
+
int ret, i;
|
|
127
|
+
|
|
128
|
+
if (argc > 1)
|
|
129
|
+
return T_EXIT_SKIP;
|
|
130
|
+
|
|
131
|
+
ret = io_uring_queue_init(2, &ring, 0);
|
|
132
|
+
if (ret) {
|
|
133
|
+
fprintf(stderr, "io_uring_queue_init failed for ring1: %d\n", ret);
|
|
134
|
+
return T_EXIT_FAIL;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
ret = io_uring_queue_init(2, &ring2, 0);
|
|
138
|
+
if (ret) {
|
|
139
|
+
fprintf(stderr, "io_uring_queue_init failed for ring2: %d\n", ret);
|
|
140
|
+
return T_EXIT_FAIL;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
ret = send_msg(&ring, ring2.ring_fd);
|
|
144
|
+
if (ret) {
|
|
145
|
+
if (ret != T_EXIT_SKIP)
|
|
146
|
+
fprintf(stderr, "send_msg failed: %d\n", ret);
|
|
147
|
+
return ret;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
ret = recv_msg(&ring2);
|
|
151
|
+
if (ret) {
|
|
152
|
+
fprintf(stderr, "recv_msg failed: %d\n", ret);
|
|
153
|
+
return ret;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
for (i = 0; i < 8; i++) {
|
|
157
|
+
ret = send_msg(&ring, ring2.ring_fd);
|
|
158
|
+
if (ret) {
|
|
159
|
+
if (ret != T_EXIT_SKIP)
|
|
160
|
+
fprintf(stderr, "send_msg failed: %d\n", ret);
|
|
161
|
+
return ret;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
for (i = 0; i < 8; i++) {
|
|
166
|
+
ret = recv_msg(&ring2);
|
|
167
|
+
if (ret) {
|
|
168
|
+
fprintf(stderr, "recv_msg failed: %d\n", ret);
|
|
169
|
+
return ret;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
pthread_barrier_init(&d.barrier, NULL, 2);
|
|
174
|
+
d.fd = -1;
|
|
175
|
+
pthread_create(&thread, NULL, thread_fn, &d);
|
|
176
|
+
pthread_barrier_wait(&d.barrier);
|
|
177
|
+
if (d.fd == -1)
|
|
178
|
+
return T_EXIT_FAIL;
|
|
179
|
+
|
|
180
|
+
ret = send_msg(&ring, d.fd);
|
|
181
|
+
if (ret) {
|
|
182
|
+
fprintf(stderr, "send msg failed: %d\n", ret);
|
|
183
|
+
return ret;
|
|
184
|
+
}
|
|
185
|
+
pthread_join(thread, &ret2);
|
|
186
|
+
if (ret2) {
|
|
187
|
+
fprintf(stderr, "Remote test failed\n");
|
|
188
|
+
return T_EXIT_FAIL;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return T_EXIT_PASS;
|
|
192
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: test ring messaging command
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
#include <errno.h>
|
|
7
|
+
#include <stdio.h>
|
|
8
|
+
#include <unistd.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include <string.h>
|
|
11
|
+
#include <fcntl.h>
|
|
12
|
+
|
|
13
|
+
#include "liburing.h"
|
|
14
|
+
#include "helpers.h"
|
|
15
|
+
|
|
16
|
+
static int no_msg;
|
|
17
|
+
|
|
18
|
+
static int test(struct io_uring *ring, unsigned dst_flags)
|
|
19
|
+
{
|
|
20
|
+
struct io_uring_params p = { };
|
|
21
|
+
struct io_uring_cqe *cqe;
|
|
22
|
+
struct io_uring_sqe *sqe;
|
|
23
|
+
struct io_uring dst;
|
|
24
|
+
int ret, i, err_ret = T_EXIT_FAIL;
|
|
25
|
+
|
|
26
|
+
p.flags = dst_flags | IORING_SETUP_CQSIZE;
|
|
27
|
+
p.cq_entries = 4;
|
|
28
|
+
ret = io_uring_queue_init_params(4, &dst, &p);
|
|
29
|
+
if (ret) {
|
|
30
|
+
fprintf(stderr, "Destination ring create failed %d\n", ret);
|
|
31
|
+
return T_EXIT_FAIL;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for (i = 0; i < 8; i++) {
|
|
35
|
+
sqe = io_uring_get_sqe(ring);
|
|
36
|
+
if (!sqe) {
|
|
37
|
+
fprintf(stderr, "get sqe failed\n");
|
|
38
|
+
goto err;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
io_uring_prep_msg_ring(sqe, dst.ring_fd, 0x10, 0x1234, 0);
|
|
42
|
+
sqe->user_data = i + 1;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
ret = io_uring_submit(ring);
|
|
46
|
+
if (ret != 8) {
|
|
47
|
+
/*
|
|
48
|
+
* Likely an old kernel that doesn't support the opcode,
|
|
49
|
+
* just skip the test.
|
|
50
|
+
*/
|
|
51
|
+
if (ret == 1) {
|
|
52
|
+
err_ret = T_EXIT_SKIP;
|
|
53
|
+
no_msg = 1;
|
|
54
|
+
goto err;
|
|
55
|
+
}
|
|
56
|
+
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
|
57
|
+
goto err;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
for (i = 0; i < 8; i++) {
|
|
61
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
|
62
|
+
if (ret < 0) {
|
|
63
|
+
fprintf(stderr, "wait completion %d\n", ret);
|
|
64
|
+
goto err;
|
|
65
|
+
}
|
|
66
|
+
switch (cqe->user_data) {
|
|
67
|
+
case 1 ... 8:
|
|
68
|
+
if (cqe->res == -EINVAL || cqe->res == -EOPNOTSUPP) {
|
|
69
|
+
no_msg = 1;
|
|
70
|
+
goto out;
|
|
71
|
+
}
|
|
72
|
+
if (cqe->res != 0) {
|
|
73
|
+
fprintf(stderr, "cqe res %d\n", cqe->res);
|
|
74
|
+
goto err;
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
case 0x1234:
|
|
78
|
+
if (cqe->res != 0x10) {
|
|
79
|
+
fprintf(stderr, "invalid len %x\n", cqe->res);
|
|
80
|
+
goto err;
|
|
81
|
+
}
|
|
82
|
+
break;
|
|
83
|
+
default:
|
|
84
|
+
fprintf(stderr, "Invalid user_data\n");
|
|
85
|
+
goto err;
|
|
86
|
+
}
|
|
87
|
+
io_uring_cqe_seen(ring, cqe);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
for (i = 0; i < 8; i++) {
|
|
91
|
+
ret = io_uring_wait_cqe(&dst, &cqe);
|
|
92
|
+
if (ret < 0) {
|
|
93
|
+
fprintf(stderr, "wait completion %d\n", ret);
|
|
94
|
+
goto err;
|
|
95
|
+
}
|
|
96
|
+
switch (cqe->user_data) {
|
|
97
|
+
case 0x1234:
|
|
98
|
+
if (cqe->res != 0x10) {
|
|
99
|
+
fprintf(stderr, "invalid len %x\n", cqe->res);
|
|
100
|
+
goto err;
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
default:
|
|
104
|
+
fprintf(stderr, "Invalid user_data\n");
|
|
105
|
+
goto err;
|
|
106
|
+
}
|
|
107
|
+
io_uring_cqe_seen(&dst, cqe);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
out:
|
|
111
|
+
io_uring_queue_exit(&dst);
|
|
112
|
+
return no_msg ? T_EXIT_SKIP : T_EXIT_PASS;
|
|
113
|
+
err:
|
|
114
|
+
io_uring_queue_exit(&dst);
|
|
115
|
+
return err_ret;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
int main(int argc, char *argv[])
|
|
119
|
+
{
|
|
120
|
+
struct io_uring src;
|
|
121
|
+
int ret;
|
|
122
|
+
|
|
123
|
+
if (argc > 1)
|
|
124
|
+
return T_EXIT_SKIP;
|
|
125
|
+
|
|
126
|
+
ret = io_uring_queue_init(8, &src, 0);
|
|
127
|
+
if (ret) {
|
|
128
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
|
129
|
+
return T_EXIT_FAIL;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
ret = test(&src, 0);
|
|
133
|
+
if (ret && !no_msg) {
|
|
134
|
+
fprintf(stderr, "test failed\n");
|
|
135
|
+
return ret;
|
|
136
|
+
}
|
|
137
|
+
if (no_msg)
|
|
138
|
+
return T_EXIT_SKIP;
|
|
139
|
+
|
|
140
|
+
ret = test(&src, IORING_SETUP_IOPOLL);
|
|
141
|
+
if (ret) {
|
|
142
|
+
fprintf(stderr, "test IOPOLL failed\n");
|
|
143
|
+
return ret;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
ret = test(&src, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER);
|
|
147
|
+
if (ret) {
|
|
148
|
+
fprintf(stderr, "test defer failed\n");
|
|
149
|
+
return ret;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
ret = test(&src, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_IOPOLL);
|
|
153
|
+
if (ret) {
|
|
154
|
+
fprintf(stderr, "test defer IOPOLL failed\n");
|
|
155
|
+
return ret;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return T_EXIT_PASS;
|
|
159
|
+
}
|