polyphony 0.84 → 0.86

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.
Files changed (241) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -0
  3. data/Gemfile.lock +1 -1
  4. data/Rakefile +1 -1
  5. data/examples/core/multi_suspend.rb +39 -0
  6. data/examples/core/shutdown_all_children.rb +41 -0
  7. data/examples/io/gzip.rb +8 -0
  8. data/examples/io/splice_echo_server.rb +15 -0
  9. data/ext/polyphony/backend_io_uring.c +57 -31
  10. data/ext/polyphony/io_extensions.c +137 -26
  11. data/lib/polyphony/extensions/fiber.rb +3 -1
  12. data/lib/polyphony/extensions/io.rb +4 -0
  13. data/lib/polyphony/extensions/pipe.rb +4 -0
  14. data/lib/polyphony/extensions/socket.rb +4 -0
  15. data/lib/polyphony/version.rb +1 -1
  16. data/polyphony.gemspec +1 -1
  17. data/test/test_backend.rb +1 -1
  18. data/test/test_fiber.rb +5 -2
  19. data/test/test_signal.rb +3 -3
  20. data/vendor/liburing/.github/pull_request_template.md +86 -0
  21. data/vendor/liburing/.github/workflows/build.yml +85 -0
  22. data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
  23. data/vendor/liburing/.gitignore +149 -0
  24. data/vendor/liburing/COPYING +502 -0
  25. data/vendor/liburing/COPYING.GPL +339 -0
  26. data/vendor/liburing/LICENSE +7 -0
  27. data/vendor/liburing/Makefile +82 -0
  28. data/vendor/liburing/Makefile.common +5 -0
  29. data/vendor/liburing/Makefile.quiet +11 -0
  30. data/vendor/liburing/README +46 -0
  31. data/vendor/liburing/configure +486 -0
  32. data/vendor/liburing/debian/README.Debian +7 -0
  33. data/vendor/liburing/debian/changelog +27 -0
  34. data/vendor/liburing/debian/compat +1 -0
  35. data/vendor/liburing/debian/control +48 -0
  36. data/vendor/liburing/debian/copyright +49 -0
  37. data/vendor/liburing/debian/liburing-dev.install +4 -0
  38. data/vendor/liburing/debian/liburing-dev.manpages +6 -0
  39. data/vendor/liburing/debian/liburing1-udeb.install +1 -0
  40. data/vendor/liburing/debian/liburing1.install +1 -0
  41. data/vendor/liburing/debian/liburing1.symbols +32 -0
  42. data/vendor/liburing/debian/patches/series +1 -0
  43. data/vendor/liburing/debian/rules +81 -0
  44. data/vendor/liburing/debian/source/format +1 -0
  45. data/vendor/liburing/debian/source/local-options +2 -0
  46. data/vendor/liburing/debian/source/options +1 -0
  47. data/vendor/liburing/debian/watch +3 -0
  48. data/vendor/liburing/examples/Makefile +38 -0
  49. data/vendor/liburing/examples/io_uring-cp.c +282 -0
  50. data/vendor/liburing/examples/io_uring-test.c +112 -0
  51. data/vendor/liburing/examples/link-cp.c +193 -0
  52. data/vendor/liburing/examples/ucontext-cp.c +273 -0
  53. data/vendor/liburing/liburing.pc.in +12 -0
  54. data/vendor/liburing/liburing.spec +66 -0
  55. data/vendor/liburing/make-debs.sh +53 -0
  56. data/vendor/liburing/man/io_uring.7 +754 -0
  57. data/vendor/liburing/man/io_uring_cq_advance.3 +35 -0
  58. data/vendor/liburing/man/io_uring_cq_ready.3 +25 -0
  59. data/vendor/liburing/man/io_uring_cqe_get_data.3 +34 -0
  60. data/vendor/liburing/man/io_uring_cqe_seen.3 +32 -0
  61. data/vendor/liburing/man/io_uring_enter.2 +1483 -0
  62. data/vendor/liburing/man/io_uring_free_probe.3 +24 -0
  63. data/vendor/liburing/man/io_uring_get_probe.3 +29 -0
  64. data/vendor/liburing/man/io_uring_get_sqe.3 +38 -0
  65. data/vendor/liburing/man/io_uring_opcode_supported.3 +29 -0
  66. data/vendor/liburing/man/io_uring_prep_msg_ring.3 +58 -0
  67. data/vendor/liburing/man/io_uring_prep_read.3 +50 -0
  68. data/vendor/liburing/man/io_uring_prep_read_fixed.3 +54 -0
  69. data/vendor/liburing/man/io_uring_prep_readv.3 +51 -0
  70. data/vendor/liburing/man/io_uring_prep_readv2.3 +79 -0
  71. data/vendor/liburing/man/io_uring_prep_write.3 +50 -0
  72. data/vendor/liburing/man/io_uring_prep_write_fixed.3 +54 -0
  73. data/vendor/liburing/man/io_uring_prep_writev.3 +51 -0
  74. data/vendor/liburing/man/io_uring_prep_writev2.3 +78 -0
  75. data/vendor/liburing/man/io_uring_queue_exit.3 +27 -0
  76. data/vendor/liburing/man/io_uring_queue_init.3 +44 -0
  77. data/vendor/liburing/man/io_uring_register.2 +688 -0
  78. data/vendor/liburing/man/io_uring_register_buffers.3 +41 -0
  79. data/vendor/liburing/man/io_uring_register_files.3 +35 -0
  80. data/vendor/liburing/man/io_uring_setup.2 +534 -0
  81. data/vendor/liburing/man/io_uring_sq_ready.3 +25 -0
  82. data/vendor/liburing/man/io_uring_sq_space_left.3 +25 -0
  83. data/vendor/liburing/man/io_uring_sqe_set_data.3 +30 -0
  84. data/vendor/liburing/man/io_uring_sqe_set_flags.3 +60 -0
  85. data/vendor/liburing/man/io_uring_sqring_wait.3 +30 -0
  86. data/vendor/liburing/man/io_uring_submit.3 +29 -0
  87. data/vendor/liburing/man/io_uring_submit_and_wait.3 +34 -0
  88. data/vendor/liburing/man/io_uring_submit_and_wait_timeout.3 +49 -0
  89. data/vendor/liburing/man/io_uring_unregister_buffers.3 +26 -0
  90. data/vendor/liburing/man/io_uring_unregister_files.3 +26 -0
  91. data/vendor/liburing/man/io_uring_wait_cqe.3 +33 -0
  92. data/vendor/liburing/man/io_uring_wait_cqe_nr.3 +36 -0
  93. data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +39 -0
  94. data/vendor/liburing/man/io_uring_wait_cqes.3 +46 -0
  95. data/vendor/liburing/src/Makefile +89 -0
  96. data/vendor/liburing/src/arch/aarch64/syscall.h +95 -0
  97. data/vendor/liburing/src/arch/generic/lib.h +21 -0
  98. data/vendor/liburing/src/arch/generic/syscall.h +87 -0
  99. data/vendor/liburing/src/arch/syscall-defs.h +67 -0
  100. data/vendor/liburing/src/arch/x86/lib.h +32 -0
  101. data/vendor/liburing/src/arch/x86/syscall.h +160 -0
  102. data/vendor/liburing/src/include/liburing/barrier.h +81 -0
  103. data/vendor/liburing/src/include/liburing/io_uring.h +442 -0
  104. data/vendor/liburing/src/include/liburing.h +921 -0
  105. data/vendor/liburing/src/int_flags.h +8 -0
  106. data/vendor/liburing/src/lib.h +57 -0
  107. data/vendor/liburing/src/liburing.map +53 -0
  108. data/vendor/liburing/src/nolibc.c +48 -0
  109. data/vendor/liburing/src/queue.c +403 -0
  110. data/vendor/liburing/src/register.c +293 -0
  111. data/vendor/liburing/src/setup.c +332 -0
  112. data/vendor/liburing/src/syscall.c +47 -0
  113. data/vendor/liburing/src/syscall.h +103 -0
  114. data/vendor/liburing/test/232c93d07b74-test.c +306 -0
  115. data/vendor/liburing/test/35fa71a030ca-test.c +329 -0
  116. data/vendor/liburing/test/500f9fbadef8-test.c +89 -0
  117. data/vendor/liburing/test/7ad0e4b2f83c-test.c +93 -0
  118. data/vendor/liburing/test/8a9973408177-test.c +106 -0
  119. data/vendor/liburing/test/917257daa0fe-test.c +53 -0
  120. data/vendor/liburing/test/Makefile +244 -0
  121. data/vendor/liburing/test/a0908ae19763-test.c +58 -0
  122. data/vendor/liburing/test/a4c0b3decb33-test.c +180 -0
  123. data/vendor/liburing/test/accept-link.c +254 -0
  124. data/vendor/liburing/test/accept-reuse.c +164 -0
  125. data/vendor/liburing/test/accept-test.c +79 -0
  126. data/vendor/liburing/test/accept.c +477 -0
  127. data/vendor/liburing/test/across-fork.c +283 -0
  128. data/vendor/liburing/test/b19062a56726-test.c +53 -0
  129. data/vendor/liburing/test/b5837bd5311d-test.c +77 -0
  130. data/vendor/liburing/test/ce593a6c480a-test.c +136 -0
  131. data/vendor/liburing/test/close-opath.c +122 -0
  132. data/vendor/liburing/test/config +10 -0
  133. data/vendor/liburing/test/connect.c +398 -0
  134. data/vendor/liburing/test/cq-full.c +96 -0
  135. data/vendor/liburing/test/cq-overflow.c +294 -0
  136. data/vendor/liburing/test/cq-peek-batch.c +102 -0
  137. data/vendor/liburing/test/cq-ready.c +94 -0
  138. data/vendor/liburing/test/cq-size.c +64 -0
  139. data/vendor/liburing/test/d4ae271dfaae-test.c +96 -0
  140. data/vendor/liburing/test/d77a67ed5f27-test.c +65 -0
  141. data/vendor/liburing/test/defer.c +307 -0
  142. data/vendor/liburing/test/double-poll-crash.c +185 -0
  143. data/vendor/liburing/test/drop-submit.c +92 -0
  144. data/vendor/liburing/test/eeed8b54e0df-test.c +114 -0
  145. data/vendor/liburing/test/empty-eownerdead.c +45 -0
  146. data/vendor/liburing/test/eventfd-disable.c +151 -0
  147. data/vendor/liburing/test/eventfd-reg.c +76 -0
  148. data/vendor/liburing/test/eventfd-ring.c +97 -0
  149. data/vendor/liburing/test/eventfd.c +112 -0
  150. data/vendor/liburing/test/exec-target.c +6 -0
  151. data/vendor/liburing/test/exit-no-cleanup.c +117 -0
  152. data/vendor/liburing/test/fadvise.c +202 -0
  153. data/vendor/liburing/test/fallocate.c +249 -0
  154. data/vendor/liburing/test/fc2a85cb02ef-test.c +131 -0
  155. data/vendor/liburing/test/file-register.c +858 -0
  156. data/vendor/liburing/test/file-update.c +173 -0
  157. data/vendor/liburing/test/file-verify.c +629 -0
  158. data/vendor/liburing/test/files-exit-hang-poll.c +128 -0
  159. data/vendor/liburing/test/files-exit-hang-timeout.c +134 -0
  160. data/vendor/liburing/test/fixed-link.c +90 -0
  161. data/vendor/liburing/test/fpos.c +252 -0
  162. data/vendor/liburing/test/fsync.c +224 -0
  163. data/vendor/liburing/test/hardlink.c +136 -0
  164. data/vendor/liburing/test/helpers.c +135 -0
  165. data/vendor/liburing/test/helpers.h +67 -0
  166. data/vendor/liburing/test/io-cancel.c +550 -0
  167. data/vendor/liburing/test/io_uring_enter.c +296 -0
  168. data/vendor/liburing/test/io_uring_register.c +676 -0
  169. data/vendor/liburing/test/io_uring_setup.c +192 -0
  170. data/vendor/liburing/test/iopoll.c +372 -0
  171. data/vendor/liburing/test/lfs-openat-write.c +119 -0
  172. data/vendor/liburing/test/lfs-openat.c +275 -0
  173. data/vendor/liburing/test/link-timeout.c +1107 -0
  174. data/vendor/liburing/test/link.c +496 -0
  175. data/vendor/liburing/test/link_drain.c +229 -0
  176. data/vendor/liburing/test/madvise.c +195 -0
  177. data/vendor/liburing/test/mkdir.c +108 -0
  178. data/vendor/liburing/test/msg-ring.c +234 -0
  179. data/vendor/liburing/test/multicqes_drain.c +387 -0
  180. data/vendor/liburing/test/nop-all-sizes.c +99 -0
  181. data/vendor/liburing/test/nop.c +115 -0
  182. data/vendor/liburing/test/open-close.c +261 -0
  183. data/vendor/liburing/test/openat2.c +308 -0
  184. data/vendor/liburing/test/personality.c +204 -0
  185. data/vendor/liburing/test/pipe-eof.c +83 -0
  186. data/vendor/liburing/test/pipe-reuse.c +105 -0
  187. data/vendor/liburing/test/poll-cancel-ton.c +135 -0
  188. data/vendor/liburing/test/poll-cancel.c +228 -0
  189. data/vendor/liburing/test/poll-link.c +230 -0
  190. data/vendor/liburing/test/poll-many.c +208 -0
  191. data/vendor/liburing/test/poll-mshot-update.c +273 -0
  192. data/vendor/liburing/test/poll-ring.c +48 -0
  193. data/vendor/liburing/test/poll-v-poll.c +353 -0
  194. data/vendor/liburing/test/poll.c +109 -0
  195. data/vendor/liburing/test/pollfree.c +426 -0
  196. data/vendor/liburing/test/probe.c +135 -0
  197. data/vendor/liburing/test/read-write.c +876 -0
  198. data/vendor/liburing/test/register-restrictions.c +633 -0
  199. data/vendor/liburing/test/rename.c +135 -0
  200. data/vendor/liburing/test/ring-leak.c +173 -0
  201. data/vendor/liburing/test/ring-leak2.c +249 -0
  202. data/vendor/liburing/test/rsrc_tags.c +449 -0
  203. data/vendor/liburing/test/runtests-loop.sh +16 -0
  204. data/vendor/liburing/test/runtests.sh +170 -0
  205. data/vendor/liburing/test/rw_merge_test.c +97 -0
  206. data/vendor/liburing/test/self.c +91 -0
  207. data/vendor/liburing/test/send_recv.c +286 -0
  208. data/vendor/liburing/test/send_recvmsg.c +345 -0
  209. data/vendor/liburing/test/sendmsg_fs_cve.c +200 -0
  210. data/vendor/liburing/test/shared-wq.c +84 -0
  211. data/vendor/liburing/test/short-read.c +75 -0
  212. data/vendor/liburing/test/shutdown.c +165 -0
  213. data/vendor/liburing/test/sigfd-deadlock.c +74 -0
  214. data/vendor/liburing/test/skip-cqe.c +429 -0
  215. data/vendor/liburing/test/socket-rw-eagain.c +158 -0
  216. data/vendor/liburing/test/socket-rw-offset.c +157 -0
  217. data/vendor/liburing/test/socket-rw.c +145 -0
  218. data/vendor/liburing/test/splice.c +512 -0
  219. data/vendor/liburing/test/sq-full-cpp.cc +45 -0
  220. data/vendor/liburing/test/sq-full.c +45 -0
  221. data/vendor/liburing/test/sq-poll-dup.c +204 -0
  222. data/vendor/liburing/test/sq-poll-kthread.c +169 -0
  223. data/vendor/liburing/test/sq-poll-share.c +137 -0
  224. data/vendor/liburing/test/sq-space_left.c +159 -0
  225. data/vendor/liburing/test/sqpoll-cancel-hang.c +157 -0
  226. data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
  227. data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
  228. data/vendor/liburing/test/sqpoll-sleep.c +69 -0
  229. data/vendor/liburing/test/statx.c +172 -0
  230. data/vendor/liburing/test/stdout.c +232 -0
  231. data/vendor/liburing/test/submit-link-fail.c +154 -0
  232. data/vendor/liburing/test/submit-reuse.c +239 -0
  233. data/vendor/liburing/test/symlink.c +116 -0
  234. data/vendor/liburing/test/teardowns.c +58 -0
  235. data/vendor/liburing/test/thread-exit.c +143 -0
  236. data/vendor/liburing/test/timeout-new.c +252 -0
  237. data/vendor/liburing/test/timeout-overflow.c +204 -0
  238. data/vendor/liburing/test/timeout.c +1523 -0
  239. data/vendor/liburing/test/unlink.c +112 -0
  240. data/vendor/liburing/test/wakeup-hang.c +162 -0
  241. metadata +227 -2
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/make -f
2
+
3
+ # Uncomment this to turn on verbose mode.
4
+ #export DH_VERBOSE=1
5
+
6
+ DEB_BUILD_MAINT_OPTIONS = hardening=+bindnow
7
+ DEB_CFLAGS_MAINT_PREPEND = -Wall
8
+
9
+ include /usr/share/dpkg/default.mk
10
+ include /usr/share/dpkg/buildtools.mk
11
+
12
+ export CC
13
+
14
+ lib := liburing1
15
+ libdbg := $(lib)-dbg
16
+ libudeb := $(lib)-udeb
17
+ libdev := liburing-dev
18
+
19
+ build-indep:
20
+
21
+ build-arch:
22
+ dh_testdir
23
+
24
+ $(MAKE) CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)"
25
+
26
+ build: build-indep build-arch
27
+
28
+ clean:
29
+ dh_testdir
30
+ dh_testroot
31
+
32
+ $(MAKE) clean
33
+
34
+ dh_clean
35
+
36
+ check-arch: build-arch
37
+ dh_testdir
38
+
39
+ ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
40
+ $(MAKE) CPPFLAGS="$(CPPFLAGS)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
41
+ partcheck
42
+ endif
43
+
44
+ install-arch: check-arch
45
+ dh_testdir
46
+ dh_testroot
47
+ dh_clean
48
+ dh_installdirs
49
+
50
+ $(MAKE) install \
51
+ DESTDIR=$(CURDIR)/debian/tmp \
52
+ libdir=/lib/$(DEB_HOST_MULTIARCH) \
53
+ libdevdir=/usr/lib/$(DEB_HOST_MULTIARCH) \
54
+ relativelibdir=/lib/$(DEB_HOST_MULTIARCH)/
55
+
56
+ binary: binary-indep binary-arch
57
+
58
+ binary-indep:
59
+ # Nothing to do.
60
+
61
+ binary-arch: install-arch
62
+ dh_testdir
63
+ dh_testroot
64
+ dh_install -a
65
+ dh_installdocs -a
66
+ dh_installexamples -a
67
+ dh_installman -a
68
+ dh_lintian -a
69
+ dh_link -a
70
+ dh_strip -a --ddeb-migration='$(libdbg) (<< 0.3)'
71
+ dh_compress -a
72
+ dh_fixperms -a
73
+ dh_makeshlibs -a --add-udeb '$(libudeb)'
74
+ dh_shlibdeps -a
75
+ dh_installdeb -a
76
+ dh_gencontrol -a
77
+ dh_md5sums -a
78
+ dh_builddeb -a
79
+
80
+ .PHONY: clean build-indep build-arch build
81
+ .PHONY: install-arch binary-indep binary-arch binary
@@ -0,0 +1 @@
1
+ 3.0 (quilt)
@@ -0,0 +1,2 @@
1
+ #abort-on-upstream-changes
2
+ #unapply-patches
@@ -0,0 +1 @@
1
+ extend-diff-ignore = "(^|/)(config\.log|config-host\.h|config-host\.mak|liburing\.pc)$"
@@ -0,0 +1,3 @@
1
+ # Site Directory Pattern Version Script
2
+ version=4
3
+ https://git.kernel.dk/cgit/liburing/ snapshot\/liburing-([\d\.]+)\.tar\.(?:gz|xz) debian uupdate
@@ -0,0 +1,38 @@
1
+ CPPFLAGS ?=
2
+ override CPPFLAGS += -D_GNU_SOURCE -I../src/include/
3
+ CFLAGS ?= -g -O2 -Wall
4
+ LDFLAGS ?=
5
+ override LDFLAGS += -L../src/ -luring
6
+
7
+ include ../Makefile.quiet
8
+
9
+ ifneq ($(MAKECMDGOALS),clean)
10
+ include ../config-host.mak
11
+ endif
12
+
13
+ example_srcs := \
14
+ io_uring-cp.c \
15
+ io_uring-test.c \
16
+ link-cp.c
17
+
18
+ all_targets :=
19
+
20
+
21
+ ifdef CONFIG_HAVE_UCONTEXT
22
+ example_srcs += ucontext-cp.c
23
+ endif
24
+ all_targets += ucontext-cp
25
+
26
+ example_targets := $(patsubst %.c,%,$(patsubst %.cc,%,$(example_srcs)))
27
+ all_targets += $(example_targets)
28
+
29
+
30
+ all: $(example_targets)
31
+
32
+ %: %.c ../src/liburing.a
33
+ $(QUIET_CC)$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< $(LDFLAGS)
34
+
35
+ clean:
36
+ @rm -f $(all_targets)
37
+
38
+ .PHONY: all clean
@@ -0,0 +1,282 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * gcc -Wall -O2 -D_GNU_SOURCE -o io_uring-cp io_uring-cp.c -luring
4
+ */
5
+ #include <stdio.h>
6
+ #include <fcntl.h>
7
+ #include <string.h>
8
+ #include <stdlib.h>
9
+ #include <unistd.h>
10
+ #include <assert.h>
11
+ #include <errno.h>
12
+ #include <inttypes.h>
13
+ #include <sys/types.h>
14
+ #include <sys/stat.h>
15
+ #include <sys/ioctl.h>
16
+ #include "liburing.h"
17
+
18
+ #define QD 64
19
+ #define BS (32*1024)
20
+
21
+ static int infd, outfd;
22
+
23
+ struct io_data {
24
+ int read;
25
+ off_t first_offset, offset;
26
+ size_t first_len;
27
+ struct iovec iov;
28
+ };
29
+
30
+ static int setup_context(unsigned entries, struct io_uring *ring)
31
+ {
32
+ int ret;
33
+
34
+ ret = io_uring_queue_init(entries, ring, 0);
35
+ if (ret < 0) {
36
+ fprintf(stderr, "queue_init: %s\n", strerror(-ret));
37
+ return -1;
38
+ }
39
+
40
+ return 0;
41
+ }
42
+
43
+ static int get_file_size(int fd, off_t *size)
44
+ {
45
+ struct stat st;
46
+
47
+ if (fstat(fd, &st) < 0)
48
+ return -1;
49
+ if (S_ISREG(st.st_mode)) {
50
+ *size = st.st_size;
51
+ return 0;
52
+ } else if (S_ISBLK(st.st_mode)) {
53
+ unsigned long long bytes;
54
+
55
+ if (ioctl(fd, BLKGETSIZE64, &bytes) != 0)
56
+ return -1;
57
+
58
+ *size = bytes;
59
+ return 0;
60
+ }
61
+
62
+ return -1;
63
+ }
64
+
65
+ static void queue_prepped(struct io_uring *ring, struct io_data *data)
66
+ {
67
+ struct io_uring_sqe *sqe;
68
+
69
+ sqe = io_uring_get_sqe(ring);
70
+ assert(sqe);
71
+
72
+ if (data->read)
73
+ io_uring_prep_readv(sqe, infd, &data->iov, 1, data->offset);
74
+ else
75
+ io_uring_prep_writev(sqe, outfd, &data->iov, 1, data->offset);
76
+
77
+ io_uring_sqe_set_data(sqe, data);
78
+ }
79
+
80
+ static int queue_read(struct io_uring *ring, off_t size, off_t offset)
81
+ {
82
+ struct io_uring_sqe *sqe;
83
+ struct io_data *data;
84
+
85
+ data = malloc(size + sizeof(*data));
86
+ if (!data)
87
+ return 1;
88
+
89
+ sqe = io_uring_get_sqe(ring);
90
+ if (!sqe) {
91
+ free(data);
92
+ return 1;
93
+ }
94
+
95
+ data->read = 1;
96
+ data->offset = data->first_offset = offset;
97
+
98
+ data->iov.iov_base = data + 1;
99
+ data->iov.iov_len = size;
100
+ data->first_len = size;
101
+
102
+ io_uring_prep_readv(sqe, infd, &data->iov, 1, offset);
103
+ io_uring_sqe_set_data(sqe, data);
104
+ return 0;
105
+ }
106
+
107
+ static void queue_write(struct io_uring *ring, struct io_data *data)
108
+ {
109
+ data->read = 0;
110
+ data->offset = data->first_offset;
111
+
112
+ data->iov.iov_base = data + 1;
113
+ data->iov.iov_len = data->first_len;
114
+
115
+ queue_prepped(ring, data);
116
+ io_uring_submit(ring);
117
+ }
118
+
119
+ static int copy_file(struct io_uring *ring, off_t insize)
120
+ {
121
+ unsigned long reads, writes;
122
+ struct io_uring_cqe *cqe;
123
+ off_t write_left, offset;
124
+ int ret;
125
+
126
+ write_left = insize;
127
+ writes = reads = offset = 0;
128
+
129
+ while (insize || write_left) {
130
+ unsigned long had_reads;
131
+ int got_comp;
132
+
133
+ /*
134
+ * Queue up as many reads as we can
135
+ */
136
+ had_reads = reads;
137
+ while (insize) {
138
+ off_t this_size = insize;
139
+
140
+ if (reads + writes >= QD)
141
+ break;
142
+ if (this_size > BS)
143
+ this_size = BS;
144
+ else if (!this_size)
145
+ break;
146
+
147
+ if (queue_read(ring, this_size, offset))
148
+ break;
149
+
150
+ insize -= this_size;
151
+ offset += this_size;
152
+ reads++;
153
+ }
154
+
155
+ if (had_reads != reads) {
156
+ ret = io_uring_submit(ring);
157
+ if (ret < 0) {
158
+ fprintf(stderr, "io_uring_submit: %s\n", strerror(-ret));
159
+ break;
160
+ }
161
+ }
162
+
163
+ /*
164
+ * Queue is full at this point. Find at least one completion.
165
+ */
166
+ got_comp = 0;
167
+ while (write_left) {
168
+ struct io_data *data;
169
+
170
+ if (!got_comp) {
171
+ ret = io_uring_wait_cqe(ring, &cqe);
172
+ got_comp = 1;
173
+ } else {
174
+ ret = io_uring_peek_cqe(ring, &cqe);
175
+ if (ret == -EAGAIN) {
176
+ cqe = NULL;
177
+ ret = 0;
178
+ }
179
+ }
180
+ if (ret < 0) {
181
+ fprintf(stderr, "io_uring_peek_cqe: %s\n",
182
+ strerror(-ret));
183
+ return 1;
184
+ }
185
+ if (!cqe)
186
+ break;
187
+
188
+ data = io_uring_cqe_get_data(cqe);
189
+ if (cqe->res < 0) {
190
+ if (cqe->res == -EAGAIN) {
191
+ queue_prepped(ring, data);
192
+ io_uring_submit(ring);
193
+ io_uring_cqe_seen(ring, cqe);
194
+ continue;
195
+ }
196
+ fprintf(stderr, "cqe failed: %s\n",
197
+ strerror(-cqe->res));
198
+ return 1;
199
+ } else if ((size_t)cqe->res != data->iov.iov_len) {
200
+ /* Short read/write, adjust and requeue */
201
+ data->iov.iov_base += cqe->res;
202
+ data->iov.iov_len -= cqe->res;
203
+ data->offset += cqe->res;
204
+ queue_prepped(ring, data);
205
+ io_uring_submit(ring);
206
+ io_uring_cqe_seen(ring, cqe);
207
+ continue;
208
+ }
209
+
210
+ /*
211
+ * All done. if write, nothing else to do. if read,
212
+ * queue up corresponding write.
213
+ */
214
+ if (data->read) {
215
+ queue_write(ring, data);
216
+ write_left -= data->first_len;
217
+ reads--;
218
+ writes++;
219
+ } else {
220
+ free(data);
221
+ writes--;
222
+ }
223
+ io_uring_cqe_seen(ring, cqe);
224
+ }
225
+ }
226
+
227
+ /* wait out pending writes */
228
+ while (writes) {
229
+ struct io_data *data;
230
+
231
+ ret = io_uring_wait_cqe(ring, &cqe);
232
+ if (ret) {
233
+ fprintf(stderr, "wait_cqe=%d\n", ret);
234
+ return 1;
235
+ }
236
+ if (cqe->res < 0) {
237
+ fprintf(stderr, "write res=%d\n", cqe->res);
238
+ return 1;
239
+ }
240
+ data = io_uring_cqe_get_data(cqe);
241
+ free(data);
242
+ writes--;
243
+ io_uring_cqe_seen(ring, cqe);
244
+ }
245
+
246
+ return 0;
247
+ }
248
+
249
+ int main(int argc, char *argv[])
250
+ {
251
+ struct io_uring ring;
252
+ off_t insize;
253
+ int ret;
254
+
255
+ if (argc < 3) {
256
+ printf("%s: infile outfile\n", argv[0]);
257
+ return 1;
258
+ }
259
+
260
+ infd = open(argv[1], O_RDONLY);
261
+ if (infd < 0) {
262
+ perror("open infile");
263
+ return 1;
264
+ }
265
+ outfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
266
+ if (outfd < 0) {
267
+ perror("open outfile");
268
+ return 1;
269
+ }
270
+
271
+ if (setup_context(QD, &ring))
272
+ return 1;
273
+ if (get_file_size(infd, &insize))
274
+ return 1;
275
+
276
+ ret = copy_file(&ring, insize);
277
+
278
+ close(infd);
279
+ close(outfd);
280
+ io_uring_queue_exit(&ring);
281
+ return ret;
282
+ }
@@ -0,0 +1,112 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Simple app that demonstrates how to setup an io_uring interface,
4
+ * submit and complete IO against it, and then tear it down.
5
+ *
6
+ * gcc -Wall -O2 -D_GNU_SOURCE -o io_uring-test io_uring-test.c -luring
7
+ */
8
+ #include <stdio.h>
9
+ #include <fcntl.h>
10
+ #include <string.h>
11
+ #include <stdlib.h>
12
+ #include <sys/types.h>
13
+ #include <sys/stat.h>
14
+ #include <unistd.h>
15
+ #include "liburing.h"
16
+
17
+ #define QD 4
18
+
19
+ int main(int argc, char *argv[])
20
+ {
21
+ struct io_uring ring;
22
+ int i, fd, ret, pending, done;
23
+ struct io_uring_sqe *sqe;
24
+ struct io_uring_cqe *cqe;
25
+ struct iovec *iovecs;
26
+ struct stat sb;
27
+ ssize_t fsize;
28
+ off_t offset;
29
+ void *buf;
30
+
31
+ if (argc < 2) {
32
+ printf("%s: file\n", argv[0]);
33
+ return 1;
34
+ }
35
+
36
+ ret = io_uring_queue_init(QD, &ring, 0);
37
+ if (ret < 0) {
38
+ fprintf(stderr, "queue_init: %s\n", strerror(-ret));
39
+ return 1;
40
+ }
41
+
42
+ fd = open(argv[1], O_RDONLY | O_DIRECT);
43
+ if (fd < 0) {
44
+ perror("open");
45
+ return 1;
46
+ }
47
+
48
+ if (fstat(fd, &sb) < 0) {
49
+ perror("fstat");
50
+ return 1;
51
+ }
52
+
53
+ fsize = 0;
54
+ iovecs = calloc(QD, sizeof(struct iovec));
55
+ for (i = 0; i < QD; i++) {
56
+ if (posix_memalign(&buf, 4096, 4096))
57
+ return 1;
58
+ iovecs[i].iov_base = buf;
59
+ iovecs[i].iov_len = 4096;
60
+ fsize += 4096;
61
+ }
62
+
63
+ offset = 0;
64
+ i = 0;
65
+ do {
66
+ sqe = io_uring_get_sqe(&ring);
67
+ if (!sqe)
68
+ break;
69
+ io_uring_prep_readv(sqe, fd, &iovecs[i], 1, offset);
70
+ offset += iovecs[i].iov_len;
71
+ i++;
72
+ if (offset > sb.st_size)
73
+ break;
74
+ } while (1);
75
+
76
+ ret = io_uring_submit(&ring);
77
+ if (ret < 0) {
78
+ fprintf(stderr, "io_uring_submit: %s\n", strerror(-ret));
79
+ return 1;
80
+ } else if (ret != i) {
81
+ fprintf(stderr, "io_uring_submit submitted less %d\n", ret);
82
+ return 1;
83
+ }
84
+
85
+ done = 0;
86
+ pending = ret;
87
+ fsize = 0;
88
+ for (i = 0; i < pending; i++) {
89
+ ret = io_uring_wait_cqe(&ring, &cqe);
90
+ if (ret < 0) {
91
+ fprintf(stderr, "io_uring_wait_cqe: %s\n", strerror(-ret));
92
+ return 1;
93
+ }
94
+
95
+ done++;
96
+ ret = 0;
97
+ if (cqe->res != 4096 && cqe->res + fsize != sb.st_size) {
98
+ fprintf(stderr, "ret=%d, wanted 4096\n", cqe->res);
99
+ ret = 1;
100
+ }
101
+ fsize += cqe->res;
102
+ io_uring_cqe_seen(&ring, cqe);
103
+ if (ret)
104
+ break;
105
+ }
106
+
107
+ printf("Submitted=%d, completed=%d, bytes=%lu\n", pending, done,
108
+ (unsigned long) fsize);
109
+ close(fd);
110
+ io_uring_queue_exit(&ring);
111
+ return 0;
112
+ }
@@ -0,0 +1,193 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Very basic proof-of-concept for doing a copy with linked SQEs. Needs a
4
+ * bit of error handling and short read love.
5
+ */
6
+ #include <stdio.h>
7
+ #include <fcntl.h>
8
+ #include <string.h>
9
+ #include <stdlib.h>
10
+ #include <unistd.h>
11
+ #include <assert.h>
12
+ #include <errno.h>
13
+ #include <inttypes.h>
14
+ #include <sys/types.h>
15
+ #include <sys/stat.h>
16
+ #include <sys/ioctl.h>
17
+ #include "liburing.h"
18
+
19
+ #define QD 64
20
+ #define BS (32*1024)
21
+
22
+ struct io_data {
23
+ size_t offset;
24
+ int index;
25
+ struct iovec iov;
26
+ };
27
+
28
+ static int infd, outfd;
29
+ static int inflight;
30
+
31
+ static int setup_context(unsigned entries, struct io_uring *ring)
32
+ {
33
+ int ret;
34
+
35
+ ret = io_uring_queue_init(entries, ring, 0);
36
+ if (ret < 0) {
37
+ fprintf(stderr, "queue_init: %s\n", strerror(-ret));
38
+ return -1;
39
+ }
40
+
41
+ return 0;
42
+ }
43
+
44
+ static int get_file_size(int fd, off_t *size)
45
+ {
46
+ struct stat st;
47
+
48
+ if (fstat(fd, &st) < 0)
49
+ return -1;
50
+ if (S_ISREG(st.st_mode)) {
51
+ *size = st.st_size;
52
+ return 0;
53
+ } else if (S_ISBLK(st.st_mode)) {
54
+ unsigned long long bytes;
55
+
56
+ if (ioctl(fd, BLKGETSIZE64, &bytes) != 0)
57
+ return -1;
58
+
59
+ *size = bytes;
60
+ return 0;
61
+ }
62
+
63
+ return -1;
64
+ }
65
+
66
+ static void queue_rw_pair(struct io_uring *ring, off_t size, off_t offset)
67
+ {
68
+ struct io_uring_sqe *sqe;
69
+ struct io_data *data;
70
+ void *ptr;
71
+
72
+ ptr = malloc(size + sizeof(*data));
73
+ data = ptr + size;
74
+ data->index = 0;
75
+ data->offset = offset;
76
+ data->iov.iov_base = ptr;
77
+ data->iov.iov_len = size;
78
+
79
+ sqe = io_uring_get_sqe(ring);
80
+ io_uring_prep_readv(sqe, infd, &data->iov, 1, offset);
81
+ sqe->flags |= IOSQE_IO_LINK;
82
+ io_uring_sqe_set_data(sqe, data);
83
+
84
+ sqe = io_uring_get_sqe(ring);
85
+ io_uring_prep_writev(sqe, outfd, &data->iov, 1, offset);
86
+ io_uring_sqe_set_data(sqe, data);
87
+ }
88
+
89
+ static int handle_cqe(struct io_uring *ring, struct io_uring_cqe *cqe)
90
+ {
91
+ struct io_data *data = io_uring_cqe_get_data(cqe);
92
+ int ret = 0;
93
+
94
+ data->index++;
95
+
96
+ if (cqe->res < 0) {
97
+ if (cqe->res == -ECANCELED) {
98
+ queue_rw_pair(ring, data->iov.iov_len, data->offset);
99
+ inflight += 2;
100
+ } else {
101
+ printf("cqe error: %s\n", strerror(-cqe->res));
102
+ ret = 1;
103
+ }
104
+ }
105
+
106
+ if (data->index == 2) {
107
+ void *ptr = (void *) data - data->iov.iov_len;
108
+
109
+ free(ptr);
110
+ }
111
+ io_uring_cqe_seen(ring, cqe);
112
+ return ret;
113
+ }
114
+
115
+ static int copy_file(struct io_uring *ring, off_t insize)
116
+ {
117
+ struct io_uring_cqe *cqe;
118
+ off_t this_size;
119
+ off_t offset;
120
+
121
+ offset = 0;
122
+ while (insize) {
123
+ int has_inflight = inflight;
124
+ int depth;
125
+
126
+ while (insize && inflight < QD) {
127
+ this_size = BS;
128
+ if (this_size > insize)
129
+ this_size = insize;
130
+ queue_rw_pair(ring, this_size, offset);
131
+ offset += this_size;
132
+ insize -= this_size;
133
+ inflight += 2;
134
+ }
135
+
136
+ if (has_inflight != inflight)
137
+ io_uring_submit(ring);
138
+
139
+ if (insize)
140
+ depth = QD;
141
+ else
142
+ depth = 1;
143
+ while (inflight >= depth) {
144
+ int ret;
145
+
146
+ ret = io_uring_wait_cqe(ring, &cqe);
147
+ if (ret < 0) {
148
+ printf("wait cqe: %s\n", strerror(-ret));
149
+ return 1;
150
+ }
151
+ if (handle_cqe(ring, cqe))
152
+ return 1;
153
+ inflight--;
154
+ }
155
+ }
156
+
157
+ return 0;
158
+ }
159
+
160
+ int main(int argc, char *argv[])
161
+ {
162
+ struct io_uring ring;
163
+ off_t insize;
164
+ int ret;
165
+
166
+ if (argc < 3) {
167
+ printf("%s: infile outfile\n", argv[0]);
168
+ return 1;
169
+ }
170
+
171
+ infd = open(argv[1], O_RDONLY);
172
+ if (infd < 0) {
173
+ perror("open infile");
174
+ return 1;
175
+ }
176
+ outfd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
177
+ if (outfd < 0) {
178
+ perror("open outfile");
179
+ return 1;
180
+ }
181
+
182
+ if (setup_context(QD, &ring))
183
+ return 1;
184
+ if (get_file_size(infd, &insize))
185
+ return 1;
186
+
187
+ ret = copy_file(&ring, insize);
188
+
189
+ close(infd);
190
+ close(outfd);
191
+ io_uring_queue_exit(&ring);
192
+ return ret;
193
+ }