polyphony 0.45.0 → 0.46.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +2 -0
  3. data/.gitmodules +0 -0
  4. data/.rubocop.yml +1 -0
  5. data/CHANGELOG.md +38 -0
  6. data/Gemfile.lock +11 -3
  7. data/README.md +3 -3
  8. data/Rakefile +1 -1
  9. data/TODO.md +10 -18
  10. data/examples/adapters/redis_client.rb +3 -1
  11. data/examples/adapters/redis_pubsub_perf.rb +11 -8
  12. data/examples/adapters/sequel_mysql.rb +1 -1
  13. data/examples/adapters/sequel_pg.rb +24 -0
  14. data/examples/core/{02-awaiting-fibers.rb → await.rb} +0 -0
  15. data/examples/core/{xx-channels.rb → channels.rb} +0 -0
  16. data/examples/core/deferring-an-operation.rb +16 -0
  17. data/examples/core/{xx-erlang-style-genserver.rb → erlang-style-genserver.rb} +16 -9
  18. data/examples/core/{xx-forking.rb → forking.rb} +1 -1
  19. data/examples/core/handling-signals.rb +11 -0
  20. data/examples/core/{03-interrupting.rb → interrupt.rb} +0 -0
  21. data/examples/core/{xx-pingpong.rb → pingpong.rb} +7 -5
  22. data/examples/core/{xx-recurrent-timer.rb → recurrent-timer.rb} +1 -1
  23. data/examples/core/{xx-resource_delegate.rb → resource_delegate.rb} +3 -4
  24. data/examples/core/{01-spinning-up-fibers.rb → spin.rb} +1 -1
  25. data/examples/core/{xx-spin_error_backtrace.rb → spin_error_backtrace.rb} +1 -1
  26. data/examples/core/{xx-supervise-process.rb → supervise-process.rb} +8 -5
  27. data/examples/core/supervisor.rb +20 -0
  28. data/examples/core/{xx-thread-sleep.rb → thread-sleep.rb} +0 -0
  29. data/examples/core/{xx-thread_pool.rb → thread_pool.rb} +0 -0
  30. data/examples/core/{xx-throttling.rb → throttling.rb} +0 -0
  31. data/examples/core/{xx-timeout.rb → timeout.rb} +0 -0
  32. data/examples/core/{xx-using-a-mutex.rb → using-a-mutex.rb} +0 -0
  33. data/examples/core/{xx-worker-thread.rb → worker-thread.rb} +2 -2
  34. data/examples/io/{xx-backticks.rb → backticks.rb} +0 -0
  35. data/examples/io/{xx-echo_client.rb → echo_client.rb} +1 -1
  36. data/examples/io/{xx-echo_client_from_stdin.rb → echo_client_from_stdin.rb} +2 -2
  37. data/examples/io/{xx-echo_pipe.rb → echo_pipe.rb} +1 -1
  38. data/examples/io/{xx-echo_server.rb → echo_server.rb} +0 -0
  39. data/examples/io/{xx-echo_server_with_timeout.rb → echo_server_with_timeout.rb} +1 -1
  40. data/examples/io/{xx-echo_stdin.rb → echo_stdin.rb} +0 -0
  41. data/examples/io/{xx-happy-eyeballs.rb → happy-eyeballs.rb} +0 -0
  42. data/examples/io/{xx-httparty.rb → httparty.rb} +4 -13
  43. data/examples/io/{xx-irb.rb → irb.rb} +0 -0
  44. data/examples/io/{xx-net-http.rb → net-http.rb} +0 -0
  45. data/examples/io/{xx-open.rb → open.rb} +0 -0
  46. data/examples/io/{xx-pry.rb → pry.rb} +0 -0
  47. data/examples/io/{xx-rack_server.rb → rack_server.rb} +0 -0
  48. data/examples/io/raw.rb +14 -0
  49. data/examples/io/reline.rb +18 -0
  50. data/examples/io/{xx-system.rb → system.rb} +1 -1
  51. data/examples/io/{xx-tcpserver.rb → tcpserver.rb} +0 -0
  52. data/examples/io/{xx-tcpsocket.rb → tcpsocket.rb} +0 -0
  53. data/examples/io/tunnel.rb +6 -1
  54. data/examples/io/{xx-zip.rb → zip.rb} +0 -0
  55. data/examples/performance/fiber_transfer.rb +2 -1
  56. data/examples/performance/fs_read.rb +5 -6
  57. data/examples/performance/multi_snooze.rb +0 -1
  58. data/examples/{io/xx-switch.rb → performance/switch.rb} +2 -1
  59. data/examples/performance/thread-vs-fiber/{xx-httparty_multi.rb → httparty_multi.rb} +3 -4
  60. data/examples/performance/thread-vs-fiber/{xx-httparty_threaded.rb → httparty_threaded.rb} +0 -0
  61. data/examples/performance/thread-vs-fiber/polyphony_mt_server.rb +1 -1
  62. data/examples/performance/thread-vs-fiber/polyphony_server.rb +1 -2
  63. data/examples/performance/thread-vs-fiber/threaded_server.rb +1 -5
  64. data/examples/performance/thread_pool_perf.rb +6 -7
  65. data/ext/liburing/liburing.h +585 -0
  66. data/ext/liburing/liburing/README.md +4 -0
  67. data/ext/liburing/liburing/barrier.h +73 -0
  68. data/ext/liburing/liburing/compat.h +15 -0
  69. data/ext/liburing/liburing/io_uring.h +343 -0
  70. data/ext/liburing/queue.c +333 -0
  71. data/ext/liburing/register.c +187 -0
  72. data/ext/liburing/setup.c +210 -0
  73. data/ext/liburing/syscall.c +54 -0
  74. data/ext/liburing/syscall.h +18 -0
  75. data/ext/polyphony/backend.h +1 -16
  76. data/ext/polyphony/backend_common.h +109 -0
  77. data/ext/polyphony/backend_io_uring.c +884 -0
  78. data/ext/polyphony/backend_io_uring_context.c +73 -0
  79. data/ext/polyphony/backend_io_uring_context.h +52 -0
  80. data/ext/polyphony/{libev_backend.c → backend_libev.c} +255 -345
  81. data/ext/polyphony/event.c +1 -1
  82. data/ext/polyphony/extconf.rb +31 -13
  83. data/ext/polyphony/fiber.c +111 -27
  84. data/ext/polyphony/libev.c +4 -0
  85. data/ext/polyphony/libev.h +8 -2
  86. data/ext/polyphony/liburing.c +8 -0
  87. data/ext/polyphony/playground.c +51 -0
  88. data/ext/polyphony/polyphony.c +6 -8
  89. data/ext/polyphony/polyphony.h +29 -25
  90. data/ext/polyphony/polyphony_ext.c +13 -6
  91. data/ext/polyphony/queue.c +3 -4
  92. data/ext/polyphony/ring_buffer.c +0 -1
  93. data/ext/polyphony/runqueue.c +102 -0
  94. data/ext/polyphony/runqueue_ring_buffer.c +85 -0
  95. data/ext/polyphony/runqueue_ring_buffer.h +31 -0
  96. data/ext/polyphony/thread.c +45 -92
  97. data/lib/polyphony.rb +2 -2
  98. data/lib/polyphony/adapters/fs.rb +1 -1
  99. data/lib/polyphony/adapters/process.rb +0 -3
  100. data/lib/polyphony/adapters/redis.rb +1 -1
  101. data/lib/polyphony/adapters/trace.rb +2 -2
  102. data/lib/polyphony/core/global_api.rb +9 -12
  103. data/lib/polyphony/core/sync.rb +6 -2
  104. data/lib/polyphony/extensions/core.rb +6 -24
  105. data/lib/polyphony/extensions/debug.rb +13 -0
  106. data/lib/polyphony/extensions/fiber.rb +21 -44
  107. data/lib/polyphony/extensions/io.rb +55 -10
  108. data/lib/polyphony/extensions/socket.rb +70 -12
  109. data/lib/polyphony/version.rb +1 -1
  110. data/polyphony.gemspec +3 -2
  111. data/test/helper.rb +36 -4
  112. data/test/io_uring_test.rb +55 -0
  113. data/test/stress.rb +5 -2
  114. data/test/test_backend.rb +4 -6
  115. data/test/test_ext.rb +1 -2
  116. data/test/test_fiber.rb +31 -24
  117. data/test/test_global_api.rb +58 -31
  118. data/test/test_io.rb +58 -0
  119. data/test/test_signal.rb +11 -8
  120. data/test/test_socket.rb +17 -0
  121. data/test/test_sync.rb +21 -0
  122. data/test/test_throttler.rb +3 -6
  123. data/test/test_trace.rb +7 -5
  124. metadata +86 -76
  125. data/examples/adapters/concurrent-ruby.rb +0 -9
  126. data/examples/core/04-handling-signals.rb +0 -19
  127. data/examples/core/xx-at_exit.rb +0 -29
  128. data/examples/core/xx-backend.rb +0 -102
  129. data/examples/core/xx-caller.rb +0 -12
  130. data/examples/core/xx-daemon.rb +0 -14
  131. data/examples/core/xx-deadlock.rb +0 -8
  132. data/examples/core/xx-deferring-an-operation.rb +0 -14
  133. data/examples/core/xx-exception-backtrace.rb +0 -40
  134. data/examples/core/xx-fork-cleanup.rb +0 -22
  135. data/examples/core/xx-fork-spin.rb +0 -42
  136. data/examples/core/xx-fork-terminate.rb +0 -27
  137. data/examples/core/xx-move_on.rb +0 -23
  138. data/examples/core/xx-queue-async.rb +0 -120
  139. data/examples/core/xx-readpartial.rb +0 -18
  140. data/examples/core/xx-signals.rb +0 -16
  141. data/examples/core/xx-sleep-forever.rb +0 -9
  142. data/examples/core/xx-sleeping.rb +0 -25
  143. data/examples/core/xx-snooze-starve.rb +0 -16
  144. data/examples/core/xx-spin-fork.rb +0 -49
  145. data/examples/core/xx-state-machine.rb +0 -51
  146. data/examples/core/xx-stop.rb +0 -20
  147. data/examples/core/xx-supervisors.rb +0 -21
  148. data/examples/core/xx-thread-selector-sleep.rb +0 -51
  149. data/examples/core/xx-thread-selector-snooze.rb +0 -46
  150. data/examples/core/xx-thread-snooze.rb +0 -34
  151. data/examples/core/xx-timer-gc.rb +0 -17
  152. data/examples/core/xx-trace.rb +0 -79
  153. data/examples/performance/xx-array.rb +0 -11
  154. data/examples/performance/xx-fiber-switch.rb +0 -9
  155. data/examples/performance/xx-snooze.rb +0 -15
  156. data/examples/xx-spin.rb +0 -32
@@ -0,0 +1,187 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ #include <sys/types.h>
3
+ #include <sys/stat.h>
4
+ #include <sys/mman.h>
5
+ #include <unistd.h>
6
+ #include <errno.h>
7
+ #include <string.h>
8
+
9
+ #include "liburing/compat.h"
10
+ #include "liburing/io_uring.h"
11
+ #include "liburing.h"
12
+
13
+ #include "syscall.h"
14
+
15
+ int io_uring_register_buffers(struct io_uring *ring, const struct iovec *iovecs,
16
+ unsigned nr_iovecs)
17
+ {
18
+ int ret;
19
+
20
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_BUFFERS,
21
+ iovecs, nr_iovecs);
22
+ if (ret < 0)
23
+ return -errno;
24
+
25
+ return 0;
26
+ }
27
+
28
+ int io_uring_unregister_buffers(struct io_uring *ring)
29
+ {
30
+ int ret;
31
+
32
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_BUFFERS,
33
+ NULL, 0);
34
+ if (ret < 0)
35
+ return -errno;
36
+
37
+ return 0;
38
+ }
39
+
40
+ /*
41
+ * Register an update for an existing file set. The updates will start at
42
+ * 'off' in the original array, and 'nr_files' is the number of files we'll
43
+ * update.
44
+ *
45
+ * Returns number of files updated on success, -ERROR on failure.
46
+ */
47
+ int io_uring_register_files_update(struct io_uring *ring, unsigned off,
48
+ int *files, unsigned nr_files)
49
+ {
50
+ struct io_uring_files_update up = {
51
+ .offset = off,
52
+ .fds = (unsigned long) files,
53
+ };
54
+ int ret;
55
+
56
+ ret = __sys_io_uring_register(ring->ring_fd,
57
+ IORING_REGISTER_FILES_UPDATE, &up,
58
+ nr_files);
59
+ if (ret < 0)
60
+ return -errno;
61
+
62
+ return ret;
63
+ }
64
+
65
+ int io_uring_register_files(struct io_uring *ring, const int *files,
66
+ unsigned nr_files)
67
+ {
68
+ int ret;
69
+
70
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_FILES,
71
+ files, nr_files);
72
+ if (ret < 0)
73
+ return -errno;
74
+
75
+ return 0;
76
+ }
77
+
78
+ int io_uring_unregister_files(struct io_uring *ring)
79
+ {
80
+ int ret;
81
+
82
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_FILES,
83
+ NULL, 0);
84
+ if (ret < 0)
85
+ return -errno;
86
+
87
+ return 0;
88
+ }
89
+
90
+ int io_uring_register_eventfd(struct io_uring *ring, int event_fd)
91
+ {
92
+ int ret;
93
+
94
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_EVENTFD,
95
+ &event_fd, 1);
96
+ if (ret < 0)
97
+ return -errno;
98
+
99
+ return 0;
100
+ }
101
+
102
+ int io_uring_unregister_eventfd(struct io_uring *ring)
103
+ {
104
+ int ret;
105
+
106
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_EVENTFD,
107
+ NULL, 0);
108
+ if (ret < 0)
109
+ return -errno;
110
+
111
+ return 0;
112
+ }
113
+
114
+ int io_uring_register_eventfd_async(struct io_uring *ring, int event_fd)
115
+ {
116
+ int ret;
117
+
118
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_EVENTFD_ASYNC,
119
+ &event_fd, 1);
120
+ if (ret < 0)
121
+ return -errno;
122
+
123
+ return 0;
124
+ }
125
+
126
+ int io_uring_register_probe(struct io_uring *ring, struct io_uring_probe *p,
127
+ unsigned int nr_ops)
128
+ {
129
+ int ret;
130
+
131
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_PROBE,
132
+ p, nr_ops);
133
+ if (ret < 0)
134
+ return -errno;
135
+
136
+ return 0;
137
+ }
138
+
139
+ int io_uring_register_personality(struct io_uring *ring)
140
+ {
141
+ int ret;
142
+
143
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_PERSONALITY,
144
+ NULL, 0);
145
+ if (ret < 0)
146
+ return -errno;
147
+
148
+ return ret;
149
+ }
150
+
151
+ int io_uring_unregister_personality(struct io_uring *ring, int id)
152
+ {
153
+ int ret;
154
+
155
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_UNREGISTER_PERSONALITY,
156
+ NULL, id);
157
+ if (ret < 0)
158
+ return -errno;
159
+
160
+ return ret;
161
+ }
162
+
163
+ int io_uring_register_restrictions(struct io_uring *ring,
164
+ struct io_uring_restriction *res,
165
+ unsigned int nr_res)
166
+ {
167
+ int ret;
168
+
169
+ ret = __sys_io_uring_register(ring->ring_fd, IORING_REGISTER_RESTRICTIONS,
170
+ res, nr_res);
171
+ if (ret < 0)
172
+ return -errno;
173
+
174
+ return 0;
175
+ }
176
+
177
+ int io_uring_enable_rings(struct io_uring *ring)
178
+ {
179
+ int ret;
180
+
181
+ ret = __sys_io_uring_register(ring->ring_fd,
182
+ IORING_REGISTER_ENABLE_RINGS, NULL, 0);
183
+ if (ret < 0)
184
+ return -errno;
185
+
186
+ return ret;
187
+ }
@@ -0,0 +1,210 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ #include <sys/types.h>
3
+ #include <sys/stat.h>
4
+ #include <sys/mman.h>
5
+ #include <unistd.h>
6
+ #include <errno.h>
7
+ #include <string.h>
8
+ #include <stdlib.h>
9
+
10
+ #include "liburing/compat.h"
11
+ #include "liburing/io_uring.h"
12
+ #include "liburing.h"
13
+
14
+ #include "syscall.h"
15
+
16
+ static void io_uring_unmap_rings(struct io_uring_sq *sq, struct io_uring_cq *cq)
17
+ {
18
+ munmap(sq->ring_ptr, sq->ring_sz);
19
+ if (cq->ring_ptr && cq->ring_ptr != sq->ring_ptr)
20
+ munmap(cq->ring_ptr, cq->ring_sz);
21
+ }
22
+
23
+ static int io_uring_mmap(int fd, struct io_uring_params *p,
24
+ struct io_uring_sq *sq, struct io_uring_cq *cq)
25
+ {
26
+ size_t size;
27
+ int ret;
28
+
29
+ sq->ring_sz = p->sq_off.array + p->sq_entries * sizeof(unsigned);
30
+ cq->ring_sz = p->cq_off.cqes + p->cq_entries * sizeof(struct io_uring_cqe);
31
+
32
+ if (p->features & IORING_FEAT_SINGLE_MMAP) {
33
+ if (cq->ring_sz > sq->ring_sz)
34
+ sq->ring_sz = cq->ring_sz;
35
+ cq->ring_sz = sq->ring_sz;
36
+ }
37
+ sq->ring_ptr = mmap(0, sq->ring_sz, PROT_READ | PROT_WRITE,
38
+ MAP_SHARED | MAP_POPULATE, fd, IORING_OFF_SQ_RING);
39
+ if (sq->ring_ptr == MAP_FAILED)
40
+ return -errno;
41
+
42
+ if (p->features & IORING_FEAT_SINGLE_MMAP) {
43
+ cq->ring_ptr = sq->ring_ptr;
44
+ } else {
45
+ cq->ring_ptr = mmap(0, cq->ring_sz, PROT_READ | PROT_WRITE,
46
+ MAP_SHARED | MAP_POPULATE, fd, IORING_OFF_CQ_RING);
47
+ if (cq->ring_ptr == MAP_FAILED) {
48
+ cq->ring_ptr = NULL;
49
+ ret = -errno;
50
+ goto err;
51
+ }
52
+ }
53
+
54
+ sq->khead = sq->ring_ptr + p->sq_off.head;
55
+ sq->ktail = sq->ring_ptr + p->sq_off.tail;
56
+ sq->kring_mask = sq->ring_ptr + p->sq_off.ring_mask;
57
+ sq->kring_entries = sq->ring_ptr + p->sq_off.ring_entries;
58
+ sq->kflags = sq->ring_ptr + p->sq_off.flags;
59
+ sq->kdropped = sq->ring_ptr + p->sq_off.dropped;
60
+ sq->array = sq->ring_ptr + p->sq_off.array;
61
+
62
+ size = p->sq_entries * sizeof(struct io_uring_sqe);
63
+ sq->sqes = mmap(0, size, PROT_READ | PROT_WRITE,
64
+ MAP_SHARED | MAP_POPULATE, fd,
65
+ IORING_OFF_SQES);
66
+ if (sq->sqes == MAP_FAILED) {
67
+ ret = -errno;
68
+ err:
69
+ io_uring_unmap_rings(sq, cq);
70
+ return ret;
71
+ }
72
+
73
+ cq->khead = cq->ring_ptr + p->cq_off.head;
74
+ cq->ktail = cq->ring_ptr + p->cq_off.tail;
75
+ cq->kring_mask = cq->ring_ptr + p->cq_off.ring_mask;
76
+ cq->kring_entries = cq->ring_ptr + p->cq_off.ring_entries;
77
+ cq->koverflow = cq->ring_ptr + p->cq_off.overflow;
78
+ cq->cqes = cq->ring_ptr + p->cq_off.cqes;
79
+ if (p->cq_off.flags)
80
+ cq->kflags = cq->ring_ptr + p->cq_off.flags;
81
+ return 0;
82
+ }
83
+
84
+ /*
85
+ * For users that want to specify sq_thread_cpu or sq_thread_idle, this
86
+ * interface is a convenient helper for mmap()ing the rings.
87
+ * Returns -errno on error, or zero on success. On success, 'ring'
88
+ * contains the necessary information to read/write to the rings.
89
+ */
90
+ int io_uring_queue_mmap(int fd, struct io_uring_params *p, struct io_uring *ring)
91
+ {
92
+ int ret;
93
+
94
+ memset(ring, 0, sizeof(*ring));
95
+ ret = io_uring_mmap(fd, p, &ring->sq, &ring->cq);
96
+ if (!ret) {
97
+ ring->flags = p->flags;
98
+ ring->ring_fd = fd;
99
+ }
100
+ return ret;
101
+ }
102
+
103
+ /*
104
+ * Ensure that the mmap'ed rings aren't available to a child after a fork(2).
105
+ * This uses madvise(..., MADV_DONTFORK) on the mmap'ed ranges.
106
+ */
107
+ int io_uring_ring_dontfork(struct io_uring *ring)
108
+ {
109
+ size_t len;
110
+ int ret;
111
+
112
+ if (!ring->sq.ring_ptr || !ring->sq.sqes || !ring->cq.ring_ptr)
113
+ return -EINVAL;
114
+
115
+ len = *ring->sq.kring_entries * sizeof(struct io_uring_sqe);
116
+ ret = madvise(ring->sq.sqes, len, MADV_DONTFORK);
117
+ if (ret == -1)
118
+ return -errno;
119
+
120
+ len = ring->sq.ring_sz;
121
+ ret = madvise(ring->sq.ring_ptr, len, MADV_DONTFORK);
122
+ if (ret == -1)
123
+ return -errno;
124
+
125
+ if (ring->cq.ring_ptr != ring->sq.ring_ptr) {
126
+ len = ring->cq.ring_sz;
127
+ ret = madvise(ring->cq.ring_ptr, len, MADV_DONTFORK);
128
+ if (ret == -1)
129
+ return -errno;
130
+ }
131
+
132
+ return 0;
133
+ }
134
+
135
+ int io_uring_queue_init_params(unsigned entries, struct io_uring *ring,
136
+ struct io_uring_params *p)
137
+ {
138
+ int fd, ret;
139
+
140
+ fd = __sys_io_uring_setup(entries, p);
141
+ if (fd < 0)
142
+ return -errno;
143
+
144
+ ret = io_uring_queue_mmap(fd, p, ring);
145
+ if (ret)
146
+ close(fd);
147
+
148
+ return ret;
149
+ }
150
+
151
+ /*
152
+ * Returns -errno on error, or zero on success. On success, 'ring'
153
+ * contains the necessary information to read/write to the rings.
154
+ */
155
+ int io_uring_queue_init(unsigned entries, struct io_uring *ring, unsigned flags)
156
+ {
157
+ struct io_uring_params p;
158
+
159
+ memset(&p, 0, sizeof(p));
160
+ p.flags = flags;
161
+
162
+ return io_uring_queue_init_params(entries, ring, &p);
163
+ }
164
+
165
+ void io_uring_queue_exit(struct io_uring *ring)
166
+ {
167
+ struct io_uring_sq *sq = &ring->sq;
168
+ struct io_uring_cq *cq = &ring->cq;
169
+
170
+ munmap(sq->sqes, *sq->kring_entries * sizeof(struct io_uring_sqe));
171
+ io_uring_unmap_rings(sq, cq);
172
+ close(ring->ring_fd);
173
+ }
174
+
175
+ struct io_uring_probe *io_uring_get_probe_ring(struct io_uring *ring)
176
+ {
177
+ struct io_uring_probe *probe;
178
+ int r;
179
+
180
+ size_t len = sizeof(*probe) + 256 * sizeof(struct io_uring_probe_op);
181
+ probe = malloc(len);
182
+ memset(probe, 0, len);
183
+ r = io_uring_register_probe(ring, probe, 256);
184
+ if (r < 0)
185
+ goto fail;
186
+
187
+ return probe;
188
+ fail:
189
+ free(probe);
190
+ return NULL;
191
+ }
192
+
193
+ struct io_uring_probe *io_uring_get_probe(void)
194
+ {
195
+ struct io_uring ring;
196
+ struct io_uring_probe* probe = NULL;
197
+
198
+ int r = io_uring_queue_init(2, &ring, 0);
199
+ if (r < 0)
200
+ return NULL;
201
+
202
+ probe = io_uring_get_probe_ring(&ring);
203
+ io_uring_queue_exit(&ring);
204
+ return probe;
205
+ }
206
+
207
+ void io_uring_free_probe(struct io_uring_probe *probe)
208
+ {
209
+ free(probe);
210
+ }
@@ -0,0 +1,54 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Will go away once libc support is there
4
+ */
5
+ #include <unistd.h>
6
+ #include <sys/syscall.h>
7
+ #include <sys/uio.h>
8
+ #include "liburing/compat.h"
9
+ #include "liburing/io_uring.h"
10
+ #include "syscall.h"
11
+
12
+ #ifdef __alpha__
13
+ /*
14
+ * alpha is the only exception, all other architectures
15
+ * have common numbers for new system calls.
16
+ */
17
+ # ifndef __NR_io_uring_setup
18
+ # define __NR_io_uring_setup 535
19
+ # endif
20
+ # ifndef __NR_io_uring_enter
21
+ # define __NR_io_uring_enter 536
22
+ # endif
23
+ # ifndef __NR_io_uring_register
24
+ # define __NR_io_uring_register 537
25
+ # endif
26
+ #else /* !__alpha__ */
27
+ # ifndef __NR_io_uring_setup
28
+ # define __NR_io_uring_setup 425
29
+ # endif
30
+ # ifndef __NR_io_uring_enter
31
+ # define __NR_io_uring_enter 426
32
+ # endif
33
+ # ifndef __NR_io_uring_register
34
+ # define __NR_io_uring_register 427
35
+ # endif
36
+ #endif
37
+
38
+ int __sys_io_uring_register(int fd, unsigned opcode, const void *arg,
39
+ unsigned nr_args)
40
+ {
41
+ return syscall(__NR_io_uring_register, fd, opcode, arg, nr_args);
42
+ }
43
+
44
+ int __sys_io_uring_setup(unsigned entries, struct io_uring_params *p)
45
+ {
46
+ return syscall(__NR_io_uring_setup, entries, p);
47
+ }
48
+
49
+ int __sys_io_uring_enter(int fd, unsigned to_submit, unsigned min_complete,
50
+ unsigned flags, sigset_t *sig)
51
+ {
52
+ return syscall(__NR_io_uring_enter, fd, to_submit, min_complete,
53
+ flags, sig, _NSIG / 8);
54
+ }