uringmachine 0.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.
Files changed (307) hide show
  1. checksums.yaml +7 -0
  2. data/.github/dependabot.yml +12 -0
  3. data/.github/workflows/test.yml +35 -0
  4. data/.gitignore +59 -0
  5. data/.gitmodules +3 -0
  6. data/CHANGELOG.md +7 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +21 -0
  9. data/README.md +11 -0
  10. data/Rakefile +39 -0
  11. data/TODO.md +0 -0
  12. data/examples/echo_server.rb +52 -0
  13. data/examples/event_loop.rb +69 -0
  14. data/examples/fibers.rb +105 -0
  15. data/examples/http_server.rb +56 -0
  16. data/examples/http_server_multishot.rb +57 -0
  17. data/examples/http_server_simpler.rb +34 -0
  18. data/ext/um/extconf.rb +71 -0
  19. data/ext/um/iou.h +101 -0
  20. data/ext/um/op_ctx.c +138 -0
  21. data/ext/um/ring.c +755 -0
  22. data/ext/um/um.c +267 -0
  23. data/ext/um/um.h +97 -0
  24. data/ext/um/um_class.c +175 -0
  25. data/ext/um/um_ext.c +11 -0
  26. data/ext/um/um_op.c +87 -0
  27. data/ext/um/um_utils.c +23 -0
  28. data/lib/uringmachine/version.rb +3 -0
  29. data/lib/uringmachine.rb +8 -0
  30. data/test/helper.rb +70 -0
  31. data/test/test_iou.rb +876 -0
  32. data/test/test_um.rb +168 -0
  33. data/uringmachine.gemspec +27 -0
  34. data/vendor/liburing/.github/actions/codespell/stopwords +7 -0
  35. data/vendor/liburing/.github/pull_request_template.md +86 -0
  36. data/vendor/liburing/.github/workflows/build.yml +137 -0
  37. data/vendor/liburing/.github/workflows/codespell.yml +25 -0
  38. data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
  39. data/vendor/liburing/.gitignore +41 -0
  40. data/vendor/liburing/CHANGELOG +111 -0
  41. data/vendor/liburing/CITATION.cff +11 -0
  42. data/vendor/liburing/COPYING +502 -0
  43. data/vendor/liburing/COPYING.GPL +339 -0
  44. data/vendor/liburing/LICENSE +20 -0
  45. data/vendor/liburing/Makefile +96 -0
  46. data/vendor/liburing/Makefile.common +7 -0
  47. data/vendor/liburing/Makefile.quiet +11 -0
  48. data/vendor/liburing/README +106 -0
  49. data/vendor/liburing/SECURITY.md +6 -0
  50. data/vendor/liburing/configure +624 -0
  51. data/vendor/liburing/debian/README.Debian +7 -0
  52. data/vendor/liburing/debian/changelog +38 -0
  53. data/vendor/liburing/debian/control +39 -0
  54. data/vendor/liburing/debian/copyright +49 -0
  55. data/vendor/liburing/debian/liburing-dev.install +4 -0
  56. data/vendor/liburing/debian/liburing-dev.manpages +5 -0
  57. data/vendor/liburing/debian/liburing2.install +1 -0
  58. data/vendor/liburing/debian/liburing2.symbols +56 -0
  59. data/vendor/liburing/debian/patches/series +1 -0
  60. data/vendor/liburing/debian/rules +29 -0
  61. data/vendor/liburing/debian/source/format +1 -0
  62. data/vendor/liburing/debian/source/local-options +2 -0
  63. data/vendor/liburing/debian/source/options +1 -0
  64. data/vendor/liburing/debian/watch +3 -0
  65. data/vendor/liburing/examples/Makefile +53 -0
  66. data/vendor/liburing/examples/helpers.c +62 -0
  67. data/vendor/liburing/examples/helpers.h +7 -0
  68. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  69. data/vendor/liburing/examples/io_uring-cp.c +282 -0
  70. data/vendor/liburing/examples/io_uring-test.c +112 -0
  71. data/vendor/liburing/examples/io_uring-udp.c +403 -0
  72. data/vendor/liburing/examples/link-cp.c +193 -0
  73. data/vendor/liburing/examples/napi-busy-poll-client.c +509 -0
  74. data/vendor/liburing/examples/napi-busy-poll-server.c +450 -0
  75. data/vendor/liburing/examples/poll-bench.c +101 -0
  76. data/vendor/liburing/examples/proxy.c +2461 -0
  77. data/vendor/liburing/examples/proxy.h +102 -0
  78. data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
  79. data/vendor/liburing/examples/send-zerocopy.c +658 -0
  80. data/vendor/liburing/examples/ucontext-cp.c +258 -0
  81. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  82. data/vendor/liburing/liburing.pc.in +12 -0
  83. data/vendor/liburing/liburing.spec +66 -0
  84. data/vendor/liburing/make-debs.sh +55 -0
  85. data/vendor/liburing/src/Makefile +129 -0
  86. data/vendor/liburing/src/arch/aarch64/lib.h +47 -0
  87. data/vendor/liburing/src/arch/aarch64/syscall.h +91 -0
  88. data/vendor/liburing/src/arch/generic/lib.h +17 -0
  89. data/vendor/liburing/src/arch/generic/syscall.h +100 -0
  90. data/vendor/liburing/src/arch/riscv64/lib.h +48 -0
  91. data/vendor/liburing/src/arch/riscv64/syscall.h +100 -0
  92. data/vendor/liburing/src/arch/syscall-defs.h +94 -0
  93. data/vendor/liburing/src/arch/x86/lib.h +11 -0
  94. data/vendor/liburing/src/arch/x86/syscall.h +296 -0
  95. data/vendor/liburing/src/ffi.c +15 -0
  96. data/vendor/liburing/src/include/liburing/barrier.h +81 -0
  97. data/vendor/liburing/src/include/liburing/io_uring.h +818 -0
  98. data/vendor/liburing/src/include/liburing.h +1602 -0
  99. data/vendor/liburing/src/int_flags.h +11 -0
  100. data/vendor/liburing/src/lib.h +52 -0
  101. data/vendor/liburing/src/liburing-ffi.map +211 -0
  102. data/vendor/liburing/src/liburing.map +104 -0
  103. data/vendor/liburing/src/nolibc.c +55 -0
  104. data/vendor/liburing/src/queue.c +468 -0
  105. data/vendor/liburing/src/register.c +374 -0
  106. data/vendor/liburing/src/setup.c +689 -0
  107. data/vendor/liburing/src/setup.h +9 -0
  108. data/vendor/liburing/src/syscall.c +29 -0
  109. data/vendor/liburing/src/syscall.h +53 -0
  110. data/vendor/liburing/src/version.c +21 -0
  111. data/vendor/liburing/test/232c93d07b74.c +305 -0
  112. data/vendor/liburing/test/35fa71a030ca.c +329 -0
  113. data/vendor/liburing/test/500f9fbadef8.c +91 -0
  114. data/vendor/liburing/test/7ad0e4b2f83c.c +94 -0
  115. data/vendor/liburing/test/8a9973408177.c +107 -0
  116. data/vendor/liburing/test/917257daa0fe.c +54 -0
  117. data/vendor/liburing/test/Makefile +297 -0
  118. data/vendor/liburing/test/a0908ae19763.c +59 -0
  119. data/vendor/liburing/test/a4c0b3decb33.c +181 -0
  120. data/vendor/liburing/test/accept-link.c +255 -0
  121. data/vendor/liburing/test/accept-non-empty.c +256 -0
  122. data/vendor/liburing/test/accept-reuse.c +163 -0
  123. data/vendor/liburing/test/accept-test.c +83 -0
  124. data/vendor/liburing/test/accept.c +919 -0
  125. data/vendor/liburing/test/across-fork.c +284 -0
  126. data/vendor/liburing/test/b19062a56726.c +54 -0
  127. data/vendor/liburing/test/b5837bd5311d.c +78 -0
  128. data/vendor/liburing/test/bind-listen.c +408 -0
  129. data/vendor/liburing/test/buf-ring-nommap.c +123 -0
  130. data/vendor/liburing/test/buf-ring-put.c +83 -0
  131. data/vendor/liburing/test/buf-ring.c +473 -0
  132. data/vendor/liburing/test/ce593a6c480a.c +139 -0
  133. data/vendor/liburing/test/close-opath.c +123 -0
  134. data/vendor/liburing/test/config +14 -0
  135. data/vendor/liburing/test/connect-rep.c +204 -0
  136. data/vendor/liburing/test/connect.c +442 -0
  137. data/vendor/liburing/test/coredump.c +60 -0
  138. data/vendor/liburing/test/cq-full.c +97 -0
  139. data/vendor/liburing/test/cq-overflow.c +530 -0
  140. data/vendor/liburing/test/cq-peek-batch.c +103 -0
  141. data/vendor/liburing/test/cq-ready.c +95 -0
  142. data/vendor/liburing/test/cq-size.c +65 -0
  143. data/vendor/liburing/test/d4ae271dfaae.c +96 -0
  144. data/vendor/liburing/test/d77a67ed5f27.c +65 -0
  145. data/vendor/liburing/test/defer-taskrun.c +391 -0
  146. data/vendor/liburing/test/defer-tw-timeout.c +173 -0
  147. data/vendor/liburing/test/defer.c +319 -0
  148. data/vendor/liburing/test/double-poll-crash.c +195 -0
  149. data/vendor/liburing/test/drop-submit.c +94 -0
  150. data/vendor/liburing/test/eeed8b54e0df.c +120 -0
  151. data/vendor/liburing/test/empty-eownerdead.c +45 -0
  152. data/vendor/liburing/test/eploop.c +74 -0
  153. data/vendor/liburing/test/eventfd-disable.c +179 -0
  154. data/vendor/liburing/test/eventfd-reg.c +77 -0
  155. data/vendor/liburing/test/eventfd-ring.c +98 -0
  156. data/vendor/liburing/test/eventfd.c +113 -0
  157. data/vendor/liburing/test/evloop.c +73 -0
  158. data/vendor/liburing/test/exec-target.c +6 -0
  159. data/vendor/liburing/test/exit-no-cleanup.c +117 -0
  160. data/vendor/liburing/test/fadvise.c +202 -0
  161. data/vendor/liburing/test/fallocate.c +265 -0
  162. data/vendor/liburing/test/fc2a85cb02ef.c +132 -0
  163. data/vendor/liburing/test/fd-install.c +500 -0
  164. data/vendor/liburing/test/fd-pass.c +237 -0
  165. data/vendor/liburing/test/fdinfo.c +419 -0
  166. data/vendor/liburing/test/file-register.c +1189 -0
  167. data/vendor/liburing/test/file-update.c +231 -0
  168. data/vendor/liburing/test/file-verify.c +654 -0
  169. data/vendor/liburing/test/files-exit-hang-poll.c +114 -0
  170. data/vendor/liburing/test/files-exit-hang-timeout.c +137 -0
  171. data/vendor/liburing/test/fixed-buf-iter.c +115 -0
  172. data/vendor/liburing/test/fixed-buf-merge.c +101 -0
  173. data/vendor/liburing/test/fixed-hugepage.c +411 -0
  174. data/vendor/liburing/test/fixed-link.c +90 -0
  175. data/vendor/liburing/test/fixed-reuse.c +160 -0
  176. data/vendor/liburing/test/fpos.c +255 -0
  177. data/vendor/liburing/test/fsnotify.c +118 -0
  178. data/vendor/liburing/test/fsync.c +224 -0
  179. data/vendor/liburing/test/futex.c +571 -0
  180. data/vendor/liburing/test/hardlink.c +170 -0
  181. data/vendor/liburing/test/helpers.c +318 -0
  182. data/vendor/liburing/test/helpers.h +108 -0
  183. data/vendor/liburing/test/ignore-single-mmap.c +48 -0
  184. data/vendor/liburing/test/init-mem.c +164 -0
  185. data/vendor/liburing/test/io-cancel.c +561 -0
  186. data/vendor/liburing/test/io_uring_enter.c +264 -0
  187. data/vendor/liburing/test/io_uring_passthrough.c +482 -0
  188. data/vendor/liburing/test/io_uring_register.c +503 -0
  189. data/vendor/liburing/test/io_uring_setup.c +110 -0
  190. data/vendor/liburing/test/iopoll-leak.c +85 -0
  191. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  192. data/vendor/liburing/test/iopoll.c +465 -0
  193. data/vendor/liburing/test/lfs-openat-write.c +119 -0
  194. data/vendor/liburing/test/lfs-openat.c +273 -0
  195. data/vendor/liburing/test/link-timeout.c +1108 -0
  196. data/vendor/liburing/test/link.c +497 -0
  197. data/vendor/liburing/test/link_drain.c +255 -0
  198. data/vendor/liburing/test/madvise.c +195 -0
  199. data/vendor/liburing/test/min-timeout-wait.c +354 -0
  200. data/vendor/liburing/test/min-timeout.c +233 -0
  201. data/vendor/liburing/test/mkdir.c +112 -0
  202. data/vendor/liburing/test/msg-ring-fd.c +331 -0
  203. data/vendor/liburing/test/msg-ring-flags.c +212 -0
  204. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  205. data/vendor/liburing/test/msg-ring.c +467 -0
  206. data/vendor/liburing/test/multicqes_drain.c +429 -0
  207. data/vendor/liburing/test/napi-test.c +215 -0
  208. data/vendor/liburing/test/napi-test.sh +48 -0
  209. data/vendor/liburing/test/no-mmap-inval.c +42 -0
  210. data/vendor/liburing/test/nolibc.c +62 -0
  211. data/vendor/liburing/test/nop-all-sizes.c +99 -0
  212. data/vendor/liburing/test/nop.c +177 -0
  213. data/vendor/liburing/test/nvme.h +169 -0
  214. data/vendor/liburing/test/ooo-file-unreg.c +82 -0
  215. data/vendor/liburing/test/open-close.c +261 -0
  216. data/vendor/liburing/test/open-direct-link.c +188 -0
  217. data/vendor/liburing/test/open-direct-pick.c +180 -0
  218. data/vendor/liburing/test/openat2.c +312 -0
  219. data/vendor/liburing/test/personality.c +204 -0
  220. data/vendor/liburing/test/pipe-bug.c +95 -0
  221. data/vendor/liburing/test/pipe-eof.c +83 -0
  222. data/vendor/liburing/test/pipe-reuse.c +105 -0
  223. data/vendor/liburing/test/poll-cancel-all.c +496 -0
  224. data/vendor/liburing/test/poll-cancel-ton.c +135 -0
  225. data/vendor/liburing/test/poll-cancel.c +228 -0
  226. data/vendor/liburing/test/poll-link.c +221 -0
  227. data/vendor/liburing/test/poll-many.c +230 -0
  228. data/vendor/liburing/test/poll-mshot-overflow.c +265 -0
  229. data/vendor/liburing/test/poll-mshot-update.c +323 -0
  230. data/vendor/liburing/test/poll-race-mshot.c +276 -0
  231. data/vendor/liburing/test/poll-race.c +105 -0
  232. data/vendor/liburing/test/poll-ring.c +48 -0
  233. data/vendor/liburing/test/poll-v-poll.c +353 -0
  234. data/vendor/liburing/test/poll.c +327 -0
  235. data/vendor/liburing/test/probe.c +135 -0
  236. data/vendor/liburing/test/read-before-exit.c +129 -0
  237. data/vendor/liburing/test/read-mshot-empty.c +153 -0
  238. data/vendor/liburing/test/read-mshot.c +404 -0
  239. data/vendor/liburing/test/read-write.c +1013 -0
  240. data/vendor/liburing/test/recv-msgall-stream.c +398 -0
  241. data/vendor/liburing/test/recv-msgall.c +263 -0
  242. data/vendor/liburing/test/recv-multishot.c +602 -0
  243. data/vendor/liburing/test/recvsend_bundle.c +691 -0
  244. data/vendor/liburing/test/reg-fd-only.c +131 -0
  245. data/vendor/liburing/test/reg-hint.c +56 -0
  246. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  247. data/vendor/liburing/test/regbuf-merge.c +91 -0
  248. data/vendor/liburing/test/register-restrictions.c +633 -0
  249. data/vendor/liburing/test/rename.c +132 -0
  250. data/vendor/liburing/test/ring-leak.c +283 -0
  251. data/vendor/liburing/test/ring-leak2.c +249 -0
  252. data/vendor/liburing/test/ringbuf-read.c +196 -0
  253. data/vendor/liburing/test/ringbuf-status.c +242 -0
  254. data/vendor/liburing/test/rsrc_tags.c +461 -0
  255. data/vendor/liburing/test/runtests-loop.sh +16 -0
  256. data/vendor/liburing/test/runtests-quiet.sh +11 -0
  257. data/vendor/liburing/test/runtests.sh +168 -0
  258. data/vendor/liburing/test/rw_merge_test.c +98 -0
  259. data/vendor/liburing/test/self.c +91 -0
  260. data/vendor/liburing/test/send-zerocopy.c +971 -0
  261. data/vendor/liburing/test/send_recv.c +412 -0
  262. data/vendor/liburing/test/send_recvmsg.c +444 -0
  263. data/vendor/liburing/test/shared-wq.c +84 -0
  264. data/vendor/liburing/test/short-read.c +75 -0
  265. data/vendor/liburing/test/shutdown.c +165 -0
  266. data/vendor/liburing/test/sigfd-deadlock.c +88 -0
  267. data/vendor/liburing/test/single-issuer.c +169 -0
  268. data/vendor/liburing/test/skip-cqe.c +428 -0
  269. data/vendor/liburing/test/socket-getsetsock-cmd.c +346 -0
  270. data/vendor/liburing/test/socket-io-cmd.c +237 -0
  271. data/vendor/liburing/test/socket-rw-eagain.c +149 -0
  272. data/vendor/liburing/test/socket-rw-offset.c +149 -0
  273. data/vendor/liburing/test/socket-rw.c +137 -0
  274. data/vendor/liburing/test/socket.c +408 -0
  275. data/vendor/liburing/test/splice.c +512 -0
  276. data/vendor/liburing/test/sq-full-cpp.cc +45 -0
  277. data/vendor/liburing/test/sq-full.c +45 -0
  278. data/vendor/liburing/test/sq-poll-dup.c +211 -0
  279. data/vendor/liburing/test/sq-poll-kthread.c +169 -0
  280. data/vendor/liburing/test/sq-poll-share.c +138 -0
  281. data/vendor/liburing/test/sq-space_left.c +159 -0
  282. data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
  283. data/vendor/liburing/test/sqpoll-exec.c +132 -0
  284. data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
  285. data/vendor/liburing/test/sqpoll-sleep.c +69 -0
  286. data/vendor/liburing/test/statx.c +172 -0
  287. data/vendor/liburing/test/stdout.c +232 -0
  288. data/vendor/liburing/test/submit-and-wait.c +108 -0
  289. data/vendor/liburing/test/submit-link-fail.c +156 -0
  290. data/vendor/liburing/test/submit-reuse.c +237 -0
  291. data/vendor/liburing/test/symlink.c +117 -0
  292. data/vendor/liburing/test/sync-cancel.c +235 -0
  293. data/vendor/liburing/test/teardowns.c +58 -0
  294. data/vendor/liburing/test/test.h +36 -0
  295. data/vendor/liburing/test/thread-exit.c +143 -0
  296. data/vendor/liburing/test/timeout-new.c +256 -0
  297. data/vendor/liburing/test/timeout.c +1798 -0
  298. data/vendor/liburing/test/truncate.c +186 -0
  299. data/vendor/liburing/test/tty-write-dpoll.c +60 -0
  300. data/vendor/liburing/test/unlink.c +112 -0
  301. data/vendor/liburing/test/version.c +25 -0
  302. data/vendor/liburing/test/wait-timeout.c +287 -0
  303. data/vendor/liburing/test/waitid.c +373 -0
  304. data/vendor/liburing/test/wakeup-hang.c +162 -0
  305. data/vendor/liburing/test/wq-aff.c +146 -0
  306. data/vendor/liburing/test/xattr.c +442 -0
  307. metadata +412 -0
@@ -0,0 +1,95 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test CQ ready
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 queue_n_nops(struct io_uring *ring, int n)
17
+ {
18
+ struct io_uring_sqe *sqe;
19
+ int i, ret;
20
+
21
+ for (i = 0; i < n; i++) {
22
+ sqe = io_uring_get_sqe(ring);
23
+ if (!sqe) {
24
+ printf("get sqe failed\n");
25
+ goto err;
26
+ }
27
+
28
+ io_uring_prep_nop(sqe);
29
+ }
30
+
31
+ ret = io_uring_submit(ring);
32
+ if (ret < n) {
33
+ printf("Submitted only %d\n", ret);
34
+ goto err;
35
+ } else if (ret < 0) {
36
+ printf("sqe submit failed: %d\n", ret);
37
+ goto err;
38
+ }
39
+
40
+ return 0;
41
+ err:
42
+ return 1;
43
+ }
44
+
45
+ #define CHECK_READY(ring, expected) do {\
46
+ ready = io_uring_cq_ready((ring));\
47
+ if (ready != expected) {\
48
+ printf("Got %d CQs ready, expected %d\n", ready, expected);\
49
+ goto err;\
50
+ }\
51
+ } while(0)
52
+
53
+ int main(int argc, char *argv[])
54
+ {
55
+ struct io_uring ring;
56
+ int ret;
57
+ unsigned ready;
58
+
59
+ if (argc > 1)
60
+ return T_EXIT_SKIP;
61
+
62
+ ret = io_uring_queue_init(4, &ring, 0);
63
+ if (ret) {
64
+ printf("ring setup failed\n");
65
+ return T_EXIT_FAIL;
66
+
67
+ }
68
+
69
+ CHECK_READY(&ring, 0);
70
+ if (queue_n_nops(&ring, 4))
71
+ goto err;
72
+
73
+ CHECK_READY(&ring, 4);
74
+ io_uring_cq_advance(&ring, 4);
75
+ CHECK_READY(&ring, 0);
76
+ if (queue_n_nops(&ring, 4))
77
+ goto err;
78
+
79
+ CHECK_READY(&ring, 4);
80
+
81
+ io_uring_cq_advance(&ring, 1);
82
+ CHECK_READY(&ring, 3);
83
+
84
+ io_uring_cq_advance(&ring, 2);
85
+ CHECK_READY(&ring, 1);
86
+
87
+ io_uring_cq_advance(&ring, 1);
88
+ CHECK_READY(&ring, 0);
89
+
90
+ io_uring_queue_exit(&ring);
91
+ return T_EXIT_PASS;
92
+ err:
93
+ io_uring_queue_exit(&ring);
94
+ return T_EXIT_FAIL;
95
+ }
@@ -0,0 +1,65 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test CQ ring sizing
4
+ */
5
+ #include <errno.h>
6
+ #include <stdio.h>
7
+ #include <unistd.h>
8
+ #include <stdlib.h>
9
+ #include <string.h>
10
+ #include <fcntl.h>
11
+
12
+ #include "liburing.h"
13
+ #include "helpers.h"
14
+
15
+ int main(int argc, char *argv[])
16
+ {
17
+ struct io_uring_params p;
18
+ struct io_uring ring;
19
+ int ret;
20
+
21
+ if (argc > 1)
22
+ return T_EXIT_SKIP;
23
+
24
+ memset(&p, 0, sizeof(p));
25
+ p.flags = IORING_SETUP_CQSIZE;
26
+ p.cq_entries = 64;
27
+
28
+ ret = io_uring_queue_init_params(4, &ring, &p);
29
+ if (ret) {
30
+ if (ret == -EINVAL) {
31
+ printf("Skipped, not supported on this kernel\n");
32
+ goto done;
33
+ }
34
+ printf("ring setup failed\n");
35
+ return T_EXIT_FAIL;
36
+ }
37
+
38
+ if (p.cq_entries < 64) {
39
+ printf("cq entries invalid (%d)\n", p.cq_entries);
40
+ goto err;
41
+ }
42
+ io_uring_queue_exit(&ring);
43
+
44
+ memset(&p, 0, sizeof(p));
45
+ p.flags = IORING_SETUP_CQSIZE;
46
+ p.cq_entries = 0;
47
+
48
+ ret = io_uring_queue_init_params(4, &ring, &p);
49
+ if (ret >= 0) {
50
+ printf("zero sized cq ring succeeded\n");
51
+ io_uring_queue_exit(&ring);
52
+ goto err;
53
+ }
54
+
55
+ if (ret != -EINVAL) {
56
+ printf("io_uring_queue_init_params failed, but not with -EINVAL"
57
+ ", returned error %d (%s)\n", ret, strerror(-ret));
58
+ goto err;
59
+ }
60
+
61
+ done:
62
+ return T_EXIT_PASS;
63
+ err:
64
+ return T_EXIT_FAIL;
65
+ }
@@ -0,0 +1,96 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Test case for SQPOLL missing a 'ret' clear in case of busy.
4
+ *
5
+ * Heavily based on a test case from
6
+ * Xiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
7
+ */
8
+ #include <stdio.h>
9
+ #include <stdlib.h>
10
+ #include <fcntl.h>
11
+ #include <unistd.h>
12
+ #include <string.h>
13
+
14
+ #include "helpers.h"
15
+ #include "liburing.h"
16
+
17
+ #define FILE_SIZE (128 * 1024)
18
+
19
+ int main(int argc, char *argv[])
20
+ {
21
+ struct io_uring ring;
22
+ int i, fd, ret;
23
+ struct io_uring_sqe *sqe;
24
+ struct io_uring_cqe *cqe;
25
+ struct iovec *iovecs;
26
+ struct io_uring_params p;
27
+ char *fname;
28
+ void *buf;
29
+
30
+ memset(&p, 0, sizeof(p));
31
+ p.flags = IORING_SETUP_SQPOLL;
32
+ ret = t_create_ring_params(16, &ring, &p);
33
+ if (ret == T_SETUP_SKIP)
34
+ return T_EXIT_SKIP;
35
+ else if (ret < 0)
36
+ return T_EXIT_FAIL;
37
+
38
+ if (argc > 1) {
39
+ fname = argv[1];
40
+ } else {
41
+ fname = ".sqpoll.tmp";
42
+ t_create_file(fname, FILE_SIZE);
43
+ }
44
+
45
+ fd = open(fname, O_RDONLY | O_DIRECT);
46
+ if (fname != argv[1])
47
+ unlink(fname);
48
+ if (fd < 0) {
49
+ perror("open");
50
+ goto out;
51
+ }
52
+
53
+ iovecs = t_calloc(10, sizeof(struct iovec));
54
+ for (i = 0; i < 10; i++) {
55
+ t_posix_memalign(&buf, 4096, 4096);
56
+ iovecs[i].iov_base = buf;
57
+ iovecs[i].iov_len = 4096;
58
+ }
59
+
60
+ ret = io_uring_register_files(&ring, &fd, 1);
61
+ if (ret < 0) {
62
+ fprintf(stderr, "register files %d\n", ret);
63
+ goto out;
64
+ }
65
+
66
+ for (i = 0; i < 10; i++) {
67
+ sqe = io_uring_get_sqe(&ring);
68
+ if (!sqe)
69
+ break;
70
+
71
+ io_uring_prep_readv(sqe, 0, &iovecs[i], 1, 0);
72
+ sqe->flags |= IOSQE_FIXED_FILE;
73
+
74
+ ret = io_uring_submit(&ring);
75
+ usleep(1000);
76
+ }
77
+
78
+ for (i = 0; i < 10; i++) {
79
+ ret = io_uring_wait_cqe(&ring, &cqe);
80
+ if (ret) {
81
+ fprintf(stderr, "wait_cqe=%d\n", ret);
82
+ break;
83
+ }
84
+ if (cqe->res != 4096) {
85
+ fprintf(stderr, "ret=%d, wanted 4096\n", cqe->res);
86
+ ret = 1;
87
+ break;
88
+ }
89
+ io_uring_cqe_seen(&ring, cqe);
90
+ }
91
+
92
+ close(fd);
93
+ out:
94
+ io_uring_queue_exit(&ring);
95
+ return ret;
96
+ }
@@ -0,0 +1,65 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ #include <stdio.h>
3
+ #include <unistd.h>
4
+ #include <string.h>
5
+ #include <signal.h>
6
+ #include <stdlib.h>
7
+ #include "liburing.h"
8
+ #include "helpers.h"
9
+
10
+ static void sig_alrm(int sig)
11
+ {
12
+ fprintf(stderr, "Timed out!\n");
13
+ exit(1);
14
+ }
15
+
16
+ int main(int argc, char *argv[])
17
+ {
18
+ struct io_uring_sqe *sqe;
19
+ struct io_uring_cqe *cqe;
20
+ struct io_uring_params p;
21
+ struct io_uring ring;
22
+ int ret, data;
23
+
24
+ if (argc > 1)
25
+ return T_EXIT_SKIP;
26
+
27
+ signal(SIGALRM, sig_alrm);
28
+
29
+ memset(&p, 0, sizeof(p));
30
+ p.sq_thread_idle = 100;
31
+ p.flags = IORING_SETUP_SQPOLL;
32
+ ret = t_create_ring_params(4, &ring, &p);
33
+ if (ret == T_SETUP_SKIP)
34
+ return T_EXIT_SKIP;
35
+ else if (ret < 0)
36
+ return T_EXIT_FAIL;
37
+
38
+ /* make sure sq thread is sleeping at this point */
39
+ usleep(150000);
40
+ alarm(1);
41
+
42
+ sqe = io_uring_get_sqe(&ring);
43
+ if (!sqe) {
44
+ fprintf(stderr, "sqe get failed\n");
45
+ return T_EXIT_FAIL;
46
+ }
47
+
48
+ io_uring_prep_nop(sqe);
49
+ io_uring_sqe_set_data(sqe, (void *) (unsigned long) 42);
50
+ io_uring_submit_and_wait(&ring, 1);
51
+
52
+ ret = io_uring_peek_cqe(&ring, &cqe);
53
+ if (ret) {
54
+ fprintf(stderr, "cqe get failed\n");
55
+ return 1;
56
+ }
57
+
58
+ data = (unsigned long) io_uring_cqe_get_data(cqe);
59
+ if (data != 42) {
60
+ fprintf(stderr, "invalid data: %d\n", data);
61
+ return T_EXIT_FAIL;
62
+ }
63
+
64
+ return T_EXIT_PASS;
65
+ }
@@ -0,0 +1,391 @@
1
+ // SPDX-License-Identifier: MIT
2
+ #include <errno.h>
3
+ #include <stdio.h>
4
+ #include <unistd.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <sys/eventfd.h>
8
+ #include <signal.h>
9
+ #include <poll.h>
10
+ #include <assert.h>
11
+ #include <pthread.h>
12
+ #include <sys/types.h>
13
+ #include <sys/wait.h>
14
+
15
+ #include "liburing.h"
16
+ #include "test.h"
17
+ #include "helpers.h"
18
+
19
+ #define EXEC_FILENAME ".defer-taskrun"
20
+ #define EXEC_FILESIZE (1U<<20)
21
+
22
+ static bool can_read_t(int fd, int time)
23
+ {
24
+ int ret;
25
+ struct pollfd p = {
26
+ .fd = fd,
27
+ .events = POLLIN,
28
+ };
29
+
30
+ ret = poll(&p, 1, time);
31
+
32
+ return ret == 1;
33
+ }
34
+
35
+ static bool can_read(int fd)
36
+ {
37
+ return can_read_t(fd, 0);
38
+ }
39
+
40
+ static void eventfd_clear(int fd)
41
+ {
42
+ uint64_t val;
43
+ int ret;
44
+
45
+ assert(can_read(fd));
46
+ ret = read(fd, &val, 8);
47
+ assert(ret == 8);
48
+ }
49
+
50
+ static void eventfd_trigger(int fd)
51
+ {
52
+ uint64_t val = 1;
53
+ int ret;
54
+
55
+ ret = write(fd, &val, sizeof(val));
56
+ assert(ret == sizeof(val));
57
+ }
58
+
59
+ #define CHECK(x) \
60
+ do { \
61
+ if (!(x)) { \
62
+ fprintf(stderr, "%s:%d %s failed\n", __FILE__, __LINE__, #x); \
63
+ return -1; \
64
+ } \
65
+ } while (0)
66
+
67
+
68
+ static int test_eventfd(void)
69
+ {
70
+ struct io_uring ring;
71
+ int ret;
72
+ int fda, fdb;
73
+ struct io_uring_cqe *cqe;
74
+
75
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
76
+ IORING_SETUP_DEFER_TASKRUN);
77
+ if (ret)
78
+ return ret;
79
+
80
+ fda = eventfd(0, EFD_NONBLOCK);
81
+ fdb = eventfd(0, EFD_NONBLOCK);
82
+
83
+ CHECK(fda >= 0 && fdb >= 0);
84
+
85
+ ret = io_uring_register_eventfd(&ring, fda);
86
+ if (ret)
87
+ return ret;
88
+
89
+ CHECK(!can_read(fda));
90
+ CHECK(!can_read(fdb));
91
+
92
+ io_uring_prep_poll_add(io_uring_get_sqe(&ring), fdb, POLLIN);
93
+ io_uring_submit(&ring);
94
+ CHECK(!can_read(fda)); /* poll should not have completed */
95
+
96
+ io_uring_prep_nop(io_uring_get_sqe(&ring));
97
+ io_uring_submit(&ring);
98
+ CHECK(can_read(fda)); /* nop should have */
99
+
100
+ CHECK(io_uring_peek_cqe(&ring, &cqe) == 0);
101
+ CHECK(cqe->res == 0);
102
+ io_uring_cqe_seen(&ring, cqe);
103
+ eventfd_clear(fda);
104
+
105
+ eventfd_trigger(fdb);
106
+ /* can take time due to rcu_call */
107
+ CHECK(can_read_t(fda, 1000));
108
+
109
+ /* should not have processed the cqe yet */
110
+ CHECK(io_uring_cq_ready(&ring) == 0);
111
+
112
+ io_uring_get_events(&ring);
113
+ CHECK(io_uring_cq_ready(&ring) == 1);
114
+
115
+
116
+ io_uring_queue_exit(&ring);
117
+ return 0;
118
+ }
119
+
120
+ struct thread_data {
121
+ struct io_uring ring;
122
+ int efd;
123
+ char buff[8];
124
+ };
125
+
126
+ static void *thread(void *t)
127
+ {
128
+ struct thread_data *td = t;
129
+
130
+ io_uring_enable_rings(&td->ring);
131
+ io_uring_prep_read(io_uring_get_sqe(&td->ring), td->efd, td->buff, sizeof(td->buff), 0);
132
+ io_uring_submit(&td->ring);
133
+
134
+ return NULL;
135
+ }
136
+
137
+ static int test_thread_shutdown(void)
138
+ {
139
+ pthread_t t1;
140
+ int ret;
141
+ struct thread_data td;
142
+ struct io_uring_cqe *cqe;
143
+ uint64_t val = 1;
144
+
145
+ ret = io_uring_queue_init(8, &td.ring, IORING_SETUP_SINGLE_ISSUER |
146
+ IORING_SETUP_DEFER_TASKRUN |
147
+ IORING_SETUP_R_DISABLED);
148
+ if (ret)
149
+ return ret;
150
+
151
+ CHECK(io_uring_get_events(&td.ring) == -EBADFD);
152
+
153
+ td.efd = eventfd(0, 0);
154
+ CHECK(td.efd >= 0);
155
+
156
+ CHECK(pthread_create(&t1, NULL, thread, &td) == 0);
157
+ CHECK(pthread_join(t1, NULL) == 0);
158
+
159
+ CHECK(io_uring_get_events(&td.ring) == -EEXIST);
160
+
161
+ CHECK(write(td.efd, &val, sizeof(val)) == sizeof(val));
162
+ CHECK(io_uring_wait_cqe(&td.ring, &cqe) == -EEXIST);
163
+
164
+ close(td.efd);
165
+ io_uring_queue_exit(&td.ring);
166
+ return 0;
167
+ }
168
+
169
+ static int test_exec(const char *filename)
170
+ {
171
+ int ret;
172
+ int fd;
173
+ struct io_uring ring;
174
+ pid_t fork_pid;
175
+ static char * const new_argv[] = {"1", "2", "3", NULL};
176
+ static char * const new_env[] = {NULL};
177
+ char *buff;
178
+
179
+ fork_pid = fork();
180
+ CHECK(fork_pid >= 0);
181
+ if (fork_pid > 0) {
182
+ int wstatus;
183
+
184
+ CHECK(waitpid(fork_pid, &wstatus, 0) != (pid_t)-1);
185
+ if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) == T_EXIT_FAIL) {
186
+ fprintf(stderr, "child failed %i\n", WEXITSTATUS(wstatus));
187
+ return -1;
188
+ }
189
+ return T_EXIT_PASS;
190
+ }
191
+
192
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
193
+ IORING_SETUP_DEFER_TASKRUN);
194
+ if (ret)
195
+ return ret;
196
+
197
+ if (filename) {
198
+ fd = open(filename, O_RDONLY | O_DIRECT);
199
+ if (fd < 0 && errno == EINVAL)
200
+ return T_EXIT_SKIP;
201
+ } else {
202
+ t_create_file(EXEC_FILENAME, EXEC_FILESIZE);
203
+ fd = open(EXEC_FILENAME, O_RDONLY | O_DIRECT);
204
+ if (fd < 0 && errno == EINVAL) {
205
+ unlink(EXEC_FILENAME);
206
+ return T_EXIT_SKIP;
207
+ }
208
+ unlink(EXEC_FILENAME);
209
+ }
210
+ buff = (char*)malloc(EXEC_FILESIZE);
211
+ CHECK(posix_memalign((void **)&buff, 4096, EXEC_FILESIZE) == 0);
212
+ CHECK(buff);
213
+
214
+ CHECK(fd >= 0);
215
+ io_uring_prep_read(io_uring_get_sqe(&ring), fd, buff, EXEC_FILESIZE, 0);
216
+ io_uring_submit(&ring);
217
+ ret = execve("/proc/self/exe", new_argv, new_env);
218
+ /* if we get here it failed anyway */
219
+ fprintf(stderr, "execve failed %d\n", ret);
220
+ return T_EXIT_FAIL;
221
+ }
222
+
223
+ static int test_flag(void)
224
+ {
225
+ struct io_uring ring;
226
+ int ret;
227
+ int fd;
228
+ struct io_uring_cqe *cqe;
229
+
230
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
231
+ IORING_SETUP_DEFER_TASKRUN |
232
+ IORING_SETUP_TASKRUN_FLAG);
233
+ CHECK(!ret);
234
+
235
+ fd = eventfd(0, EFD_NONBLOCK);
236
+ CHECK(fd >= 0);
237
+
238
+ io_uring_prep_poll_add(io_uring_get_sqe(&ring), fd, POLLIN);
239
+ io_uring_submit(&ring);
240
+ CHECK(!can_read(fd)); /* poll should not have completed */
241
+
242
+ eventfd_trigger(fd);
243
+ CHECK(can_read(fd));
244
+
245
+ /* should not have processed the poll cqe yet */
246
+ CHECK(io_uring_cq_ready(&ring) == 0);
247
+
248
+ /* flag should be set */
249
+ CHECK(IO_URING_READ_ONCE(*ring.sq.kflags) & IORING_SQ_TASKRUN);
250
+
251
+ /* Specifically peek, knowing we have only no cqe
252
+ * but because the flag is set, liburing should try and get more
253
+ */
254
+ ret = io_uring_peek_cqe(&ring, &cqe);
255
+
256
+ CHECK(ret == 0 && cqe);
257
+ CHECK(!(IO_URING_READ_ONCE(*ring.sq.kflags) & IORING_SQ_TASKRUN));
258
+
259
+ close(fd);
260
+ io_uring_queue_exit(&ring);
261
+ return 0;
262
+ }
263
+
264
+ static int test_ring_shutdown(void)
265
+ {
266
+ struct io_uring ring;
267
+ int ret;
268
+ int fd[2];
269
+ char buff = '\0';
270
+ char send = 'X';
271
+
272
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
273
+ IORING_SETUP_DEFER_TASKRUN |
274
+ IORING_SETUP_TASKRUN_FLAG);
275
+ CHECK(!ret);
276
+
277
+ ret = t_create_socket_pair(fd, true);
278
+ CHECK(!ret);
279
+
280
+ io_uring_prep_recv(io_uring_get_sqe(&ring), fd[0], &buff, 1, 0);
281
+ io_uring_submit(&ring);
282
+
283
+ ret = write(fd[1], &send, 1);
284
+ CHECK(ret == 1);
285
+
286
+ /* should not have processed the poll cqe yet */
287
+ CHECK(io_uring_cq_ready(&ring) == 0);
288
+ io_uring_queue_exit(&ring);
289
+
290
+ /* task work should have been processed by now */
291
+ CHECK(buff = 'X');
292
+
293
+ return 0;
294
+ }
295
+
296
+ static int test_drain(void)
297
+ {
298
+ struct io_uring ring;
299
+ int ret, i, fd[2];
300
+ struct io_uring_sqe *sqe;
301
+ struct io_uring_cqe *cqe;
302
+ struct iovec iovecs[128];
303
+ char buff[ARRAY_SIZE(iovecs)];
304
+
305
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER |
306
+ IORING_SETUP_DEFER_TASKRUN |
307
+ IORING_SETUP_TASKRUN_FLAG);
308
+ CHECK(!ret);
309
+
310
+ for (i = 0; i < ARRAY_SIZE(iovecs); i++) {
311
+ iovecs[i].iov_base = &buff[i];
312
+ iovecs[i].iov_len = 1;
313
+ }
314
+
315
+ ret = t_create_socket_pair(fd, true);
316
+ CHECK(!ret);
317
+
318
+ sqe = io_uring_get_sqe(&ring);
319
+ io_uring_prep_writev(sqe, fd[1], &iovecs[0], ARRAY_SIZE(iovecs), 0);
320
+ sqe->flags |= IOSQE_IO_DRAIN;
321
+ io_uring_submit(&ring);
322
+
323
+ for (i = 0; i < ARRAY_SIZE(iovecs); i++)
324
+ iovecs[i].iov_base = NULL;
325
+
326
+ CHECK(io_uring_wait_cqe(&ring, &cqe) == 0);
327
+ CHECK(cqe->res == 128);
328
+
329
+ close(fd[0]);
330
+ close(fd[1]);
331
+ io_uring_queue_exit(&ring);
332
+ return 0;
333
+ }
334
+
335
+ int main(int argc, char *argv[])
336
+ {
337
+ int ret;
338
+ const char *filename = NULL;
339
+
340
+ if (argc > 2)
341
+ return T_EXIT_SKIP;
342
+ if (argc == 2) {
343
+ /* This test exposes interesting behaviour with a null-blk
344
+ * device configured like:
345
+ * $ modprobe null-blk completion_nsec=100000000 irqmode=2
346
+ * and then run with $ defer-taskrun.t /dev/nullb0
347
+ */
348
+ filename = argv[1];
349
+ }
350
+
351
+ if (!t_probe_defer_taskrun())
352
+ return T_EXIT_SKIP;
353
+
354
+ ret = test_thread_shutdown();
355
+ if (ret) {
356
+ fprintf(stderr, "test_thread_shutdown failed\n");
357
+ return T_EXIT_FAIL;
358
+ }
359
+
360
+ ret = test_exec(filename);
361
+ if (ret == T_EXIT_FAIL) {
362
+ fprintf(stderr, "test_exec failed\n");
363
+ return T_EXIT_FAIL;
364
+ }
365
+
366
+ ret = test_eventfd();
367
+ if (ret) {
368
+ fprintf(stderr, "eventfd failed\n");
369
+ return T_EXIT_FAIL;
370
+ }
371
+
372
+ ret = test_flag();
373
+ if (ret) {
374
+ fprintf(stderr, "flag failed\n");
375
+ return T_EXIT_FAIL;
376
+ }
377
+
378
+ ret = test_ring_shutdown();
379
+ if (ret) {
380
+ fprintf(stderr, "test_ring_shutdown failed\n");
381
+ return T_EXIT_FAIL;
382
+ }
383
+
384
+ ret = test_drain();
385
+ if (ret) {
386
+ fprintf(stderr, "test_drain failed\n");
387
+ return T_EXIT_FAIL;
388
+ }
389
+
390
+ return T_EXIT_PASS;
391
+ }