uringmachine 0.3 → 0.4
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/CHANGELOG.md +9 -0
- data/README.md +85 -0
- data/TODO.md +5 -0
- data/examples/echo_server.rb +18 -40
- data/examples/inout.rb +19 -0
- data/examples/nc.rb +36 -0
- data/ext/um/extconf.rb +6 -15
- data/ext/um/um.c +245 -53
- data/ext/um/um.h +21 -9
- data/ext/um/um_class.c +74 -87
- data/ext/um/um_const.c +184 -0
- data/ext/um/um_op.c +10 -13
- data/ext/um/um_utils.c +48 -3
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +12 -0
- data/test/helper.rb +8 -0
- data/test/test_um.rb +227 -7
- data/vendor/liburing/.github/workflows/build.yml +29 -1
- data/vendor/liburing/.gitignore +1 -0
- data/vendor/liburing/CHANGELOG +15 -0
- data/vendor/liburing/CONTRIBUTING.md +165 -0
- data/vendor/liburing/configure +32 -0
- data/vendor/liburing/examples/Makefile +8 -1
- data/vendor/liburing/examples/kdigest.c +405 -0
- data/vendor/liburing/examples/proxy.c +75 -8
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/src/Makefile +16 -2
- data/vendor/liburing/src/include/liburing/io_uring.h +31 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
- data/vendor/liburing/src/include/liburing.h +31 -4
- data/vendor/liburing/src/liburing-ffi.map +5 -0
- data/vendor/liburing/src/liburing.map +1 -0
- data/vendor/liburing/src/queue.c +3 -0
- data/vendor/liburing/src/register.c +36 -0
- data/vendor/liburing/src/sanitize.c +176 -0
- data/vendor/liburing/src/setup.c +1 -1
- data/vendor/liburing/test/35fa71a030ca.c +7 -0
- data/vendor/liburing/test/500f9fbadef8.c +2 -0
- data/vendor/liburing/test/7ad0e4b2f83c.c +0 -25
- data/vendor/liburing/test/917257daa0fe.c +7 -0
- data/vendor/liburing/test/Makefile +31 -4
- data/vendor/liburing/test/a0908ae19763.c +7 -0
- data/vendor/liburing/test/a4c0b3decb33.c +7 -0
- data/vendor/liburing/test/accept.c +14 -4
- data/vendor/liburing/test/b19062a56726.c +7 -0
- data/vendor/liburing/test/bind-listen.c +2 -2
- data/vendor/liburing/test/buf-ring-nommap.c +10 -3
- data/vendor/liburing/test/buf-ring.c +2 -0
- data/vendor/liburing/test/coredump.c +7 -0
- data/vendor/liburing/test/cq-overflow.c +13 -1
- data/vendor/liburing/test/d4ae271dfaae.c +11 -3
- data/vendor/liburing/test/defer-taskrun.c +2 -2
- data/vendor/liburing/test/defer-tw-timeout.c +4 -1
- data/vendor/liburing/test/defer.c +2 -2
- data/vendor/liburing/test/double-poll-crash.c +1 -1
- data/vendor/liburing/test/eeed8b54e0df.c +2 -0
- data/vendor/liburing/test/eventfd.c +0 -1
- data/vendor/liburing/test/exit-no-cleanup.c +11 -0
- data/vendor/liburing/test/fadvise.c +9 -26
- data/vendor/liburing/test/fdinfo.c +9 -1
- data/vendor/liburing/test/file-register.c +14 -2
- data/vendor/liburing/test/file-update.c +1 -1
- data/vendor/liburing/test/file-verify.c +27 -16
- data/vendor/liburing/test/files-exit-hang-timeout.c +1 -2
- data/vendor/liburing/test/fixed-buf-iter.c +3 -1
- data/vendor/liburing/test/fixed-hugepage.c +12 -1
- data/vendor/liburing/test/fsnotify.c +1 -0
- data/vendor/liburing/test/futex.c +16 -4
- data/vendor/liburing/test/helpers.c +47 -0
- data/vendor/liburing/test/helpers.h +6 -0
- data/vendor/liburing/test/init-mem.c +5 -3
- data/vendor/liburing/test/io-cancel.c +0 -24
- data/vendor/liburing/test/io_uring_passthrough.c +2 -0
- data/vendor/liburing/test/io_uring_register.c +25 -6
- data/vendor/liburing/test/iopoll-leak.c +4 -0
- data/vendor/liburing/test/iopoll-overflow.c +1 -1
- data/vendor/liburing/test/iopoll.c +3 -3
- data/vendor/liburing/test/kallsyms.c +203 -0
- data/vendor/liburing/test/link-timeout.c +159 -0
- data/vendor/liburing/test/linked-defer-close.c +224 -0
- data/vendor/liburing/test/madvise.c +12 -25
- data/vendor/liburing/test/min-timeout-wait.c +0 -25
- data/vendor/liburing/test/min-timeout.c +0 -25
- data/vendor/liburing/test/mkdir.c +6 -0
- data/vendor/liburing/test/msg-ring.c +8 -2
- data/vendor/liburing/test/napi-test.c +15 -2
- data/vendor/liburing/test/no-mmap-inval.c +2 -0
- data/vendor/liburing/test/nop.c +44 -0
- data/vendor/liburing/test/ooo-file-unreg.c +1 -1
- data/vendor/liburing/test/open-close.c +40 -0
- data/vendor/liburing/test/openat2.c +37 -14
- data/vendor/liburing/test/poll-many.c +13 -7
- data/vendor/liburing/test/poll-mshot-update.c +17 -10
- data/vendor/liburing/test/poll-v-poll.c +6 -3
- data/vendor/liburing/test/pollfree.c +148 -0
- data/vendor/liburing/test/read-mshot-empty.c +156 -153
- data/vendor/liburing/test/read-mshot.c +276 -27
- data/vendor/liburing/test/read-write.c +78 -13
- data/vendor/liburing/test/recv-msgall-stream.c +3 -0
- data/vendor/liburing/test/recv-msgall.c +5 -0
- data/vendor/liburing/test/recvsend_bundle-inc.c +680 -0
- data/vendor/liburing/test/recvsend_bundle.c +92 -29
- data/vendor/liburing/test/reg-fd-only.c +14 -4
- data/vendor/liburing/test/regbuf-clone.c +187 -0
- data/vendor/liburing/test/regbuf-merge.c +7 -0
- data/vendor/liburing/test/register-restrictions.c +86 -85
- data/vendor/liburing/test/rename.c +59 -1
- data/vendor/liburing/test/ringbuf-read.c +5 -0
- data/vendor/liburing/test/ringbuf-status.c +5 -1
- data/vendor/liburing/test/runtests.sh +16 -1
- data/vendor/liburing/test/send-zerocopy.c +59 -0
- data/vendor/liburing/test/short-read.c +1 -0
- data/vendor/liburing/test/socket.c +43 -0
- data/vendor/liburing/test/splice.c +3 -1
- data/vendor/liburing/test/sq-poll-dup.c +1 -1
- data/vendor/liburing/test/sq-poll-share.c +2 -0
- data/vendor/liburing/test/sqpoll-disable-exit.c +8 -0
- data/vendor/liburing/test/sqpoll-exit-hang.c +1 -25
- data/vendor/liburing/test/sqpoll-sleep.c +1 -25
- data/vendor/liburing/test/statx.c +89 -0
- data/vendor/liburing/test/stdout.c +2 -0
- data/vendor/liburing/test/submit-and-wait.c +1 -25
- data/vendor/liburing/test/submit-reuse.c +4 -26
- data/vendor/liburing/test/symlink.c +12 -1
- data/vendor/liburing/test/sync-cancel.c +48 -21
- data/vendor/liburing/test/thread-exit.c +5 -0
- data/vendor/liburing/test/timeout-new.c +1 -26
- data/vendor/liburing/test/timeout.c +12 -26
- data/vendor/liburing/test/unlink.c +94 -1
- data/vendor/liburing/test/uring_cmd_ublk.c +1252 -0
- data/vendor/liburing/test/waitid.c +62 -8
- data/vendor/liburing/test/wq-aff.c +35 -0
- data/vendor/liburing/test/xfail_prep_link_timeout_out_of_scope.c +46 -0
- data/vendor/liburing/test/xfail_register_buffers_out_of_scope.c +51 -0
- metadata +17 -4
- data/examples/event_loop.rb +0 -69
- data/examples/fibers.rb +0 -105
data/ext/um/um_class.c
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#include "um.h"
|
|
2
|
-
#include <
|
|
2
|
+
#include <arpa/inet.h>
|
|
3
3
|
|
|
4
4
|
VALUE cUM;
|
|
5
5
|
|
|
@@ -49,52 +49,8 @@ VALUE UM_initialize(VALUE self) {
|
|
|
49
49
|
|
|
50
50
|
VALUE UM_setup_buffer_ring(VALUE self, VALUE size, VALUE count) {
|
|
51
51
|
struct um *machine = get_machine(self);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
rb_raise(rb_eRuntimeError, "Cannot setup more than BUFFER_RING_MAX_COUNT buffer rings");
|
|
55
|
-
|
|
56
|
-
struct buf_ring_descriptor *desc = machine->buffer_rings + machine->buffer_ring_count;
|
|
57
|
-
desc->buf_count = NUM2UINT(count);
|
|
58
|
-
desc->buf_size = NUM2UINT(size);
|
|
59
|
-
|
|
60
|
-
desc->br_size = sizeof(struct io_uring_buf) * desc->buf_count;
|
|
61
|
-
void *mapped = mmap(
|
|
62
|
-
NULL, desc->br_size, PROT_READ | PROT_WRITE,
|
|
63
|
-
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0
|
|
64
|
-
);
|
|
65
|
-
if (mapped == MAP_FAILED)
|
|
66
|
-
rb_raise(rb_eRuntimeError, "Failed to allocate buffer ring");
|
|
67
|
-
|
|
68
|
-
desc->br = (struct io_uring_buf_ring *)mapped;
|
|
69
|
-
io_uring_buf_ring_init(desc->br);
|
|
70
|
-
|
|
71
|
-
unsigned bg_id = machine->buffer_ring_count;
|
|
72
|
-
struct io_uring_buf_reg reg = {
|
|
73
|
-
.ring_addr = (unsigned long)desc->br,
|
|
74
|
-
.ring_entries = desc->buf_count,
|
|
75
|
-
.bgid = bg_id
|
|
76
|
-
};
|
|
77
|
-
int ret = io_uring_register_buf_ring(&machine->ring, ®, 0);
|
|
78
|
-
if (ret) {
|
|
79
|
-
munmap(desc->br, desc->br_size);
|
|
80
|
-
rb_syserr_fail(-ret, strerror(-ret));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
desc->buf_base = malloc(desc->buf_count * desc->buf_size);
|
|
84
|
-
if (!desc->buf_base) {
|
|
85
|
-
io_uring_free_buf_ring(&machine->ring, desc->br, desc->buf_count, bg_id);
|
|
86
|
-
rb_raise(rb_eRuntimeError, "Failed to allocate buffers");
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
int mask = io_uring_buf_ring_mask(desc->buf_count);
|
|
90
|
-
for (unsigned i = 0; i < desc->buf_count; i++) {
|
|
91
|
-
io_uring_buf_ring_add(
|
|
92
|
-
desc->br, desc->buf_base + i * desc->buf_size, desc->buf_size,
|
|
93
|
-
i, mask, i);
|
|
94
|
-
}
|
|
95
|
-
io_uring_buf_ring_advance(desc->br, desc->buf_count);
|
|
96
|
-
machine->buffer_ring_count++;
|
|
97
|
-
return UINT2NUM(bg_id);
|
|
52
|
+
int bgid = um_setup_buffer_ring(machine, NUM2UINT(size), NUM2UINT(count));
|
|
53
|
+
return INT2NUM(bgid);
|
|
98
54
|
}
|
|
99
55
|
|
|
100
56
|
VALUE UM_pending_count(VALUE self) {
|
|
@@ -166,6 +122,11 @@ VALUE UM_write(int argc, VALUE *argv, VALUE self) {
|
|
|
166
122
|
return um_write(machine, NUM2INT(fd), buffer, bytes);
|
|
167
123
|
}
|
|
168
124
|
|
|
125
|
+
VALUE UM_close(VALUE self, VALUE fd) {
|
|
126
|
+
struct um *machine = get_machine(self);
|
|
127
|
+
return um_close(machine, NUM2INT(fd));
|
|
128
|
+
}
|
|
129
|
+
|
|
169
130
|
VALUE UM_accept(VALUE self, VALUE fd) {
|
|
170
131
|
struct um *machine = get_machine(self);
|
|
171
132
|
return um_accept(machine, NUM2INT(fd));
|
|
@@ -176,6 +137,63 @@ VALUE UM_accept_each(VALUE self, VALUE fd) {
|
|
|
176
137
|
return um_accept_each(machine, NUM2INT(fd));
|
|
177
138
|
}
|
|
178
139
|
|
|
140
|
+
VALUE UM_socket(VALUE self, VALUE domain, VALUE type, VALUE protocol, VALUE flags) {
|
|
141
|
+
struct um *machine = get_machine(self);
|
|
142
|
+
return um_socket(machine, NUM2INT(domain), NUM2INT(type), NUM2INT(protocol), NUM2UINT(flags));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
VALUE UM_connect(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
|
146
|
+
struct um *machine = get_machine(self);
|
|
147
|
+
|
|
148
|
+
struct sockaddr_in addr;
|
|
149
|
+
memset(&addr, 0, sizeof(addr));
|
|
150
|
+
addr.sin_family = AF_INET;
|
|
151
|
+
addr.sin_addr.s_addr = inet_addr(StringValueCStr(host));
|
|
152
|
+
addr.sin_port = htons(NUM2INT(port));
|
|
153
|
+
|
|
154
|
+
return um_connect(machine, NUM2INT(fd), (struct sockaddr *)&addr, sizeof(addr));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
VALUE UM_send(VALUE self, VALUE fd, VALUE buffer, VALUE len, VALUE flags) {
|
|
158
|
+
struct um *machine = get_machine(self);
|
|
159
|
+
return um_send(machine, NUM2INT(fd), buffer, NUM2INT(len), NUM2INT(flags));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
VALUE UM_recv(VALUE self, VALUE fd, VALUE buffer, VALUE maxlen, VALUE flags) {
|
|
163
|
+
struct um *machine = get_machine(self);
|
|
164
|
+
return um_recv(machine, NUM2INT(fd), buffer, NUM2INT(maxlen), NUM2INT(flags));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
VALUE UM_bind(VALUE self, VALUE fd, VALUE host, VALUE port) {
|
|
168
|
+
struct sockaddr_in addr;
|
|
169
|
+
memset(&addr, 0, sizeof(addr));
|
|
170
|
+
addr.sin_family = AF_INET;
|
|
171
|
+
addr.sin_addr.s_addr = inet_addr(StringValueCStr(host));
|
|
172
|
+
addr.sin_port = htons(NUM2INT(port));
|
|
173
|
+
|
|
174
|
+
#ifdef HAVE_IO_URING_PREP_BIND
|
|
175
|
+
struct um *machine = get_machine(self);
|
|
176
|
+
return um_bind(machine, NUM2INT(fd), (struct sockaddr *)&addr, sizeof(addr));
|
|
177
|
+
#else
|
|
178
|
+
int res = bind(NUM2INT(fd), (struct sockaddr *)&addr, sizeof(addr));
|
|
179
|
+
if (res)
|
|
180
|
+
rb_syserr_fail(errno, strerror(errno));
|
|
181
|
+
return INT2NUM(0);
|
|
182
|
+
#endif
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
VALUE UM_listen(VALUE self, VALUE fd, VALUE backlog) {
|
|
186
|
+
#ifdef HAVE_IO_URING_PREP_LISTEN
|
|
187
|
+
struct um *machine = get_machine(self);
|
|
188
|
+
return um_listen(machine, NUM2INT(fd), NUM2INT(backlog));
|
|
189
|
+
#else
|
|
190
|
+
int res = listen(NUM2INT(fd), NUM2INT(backlog));
|
|
191
|
+
if (res)
|
|
192
|
+
rb_syserr_fail(errno, strerror(errno));
|
|
193
|
+
return INT2NUM(0);
|
|
194
|
+
#endif
|
|
195
|
+
}
|
|
196
|
+
|
|
179
197
|
void Init_UM(void) {
|
|
180
198
|
rb_ext_ractor_safe(true);
|
|
181
199
|
|
|
@@ -196,47 +214,16 @@ void Init_UM(void) {
|
|
|
196
214
|
rb_define_method(cUM, "read", UM_read, -1);
|
|
197
215
|
rb_define_method(cUM, "read_each", UM_read_each, 2);
|
|
198
216
|
rb_define_method(cUM, "write", UM_write, -1);
|
|
217
|
+
rb_define_method(cUM, "close", UM_close, 1);
|
|
199
218
|
|
|
200
219
|
rb_define_method(cUM, "accept", UM_accept, 1);
|
|
201
220
|
rb_define_method(cUM, "accept_each", UM_accept_each, 1);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
// rb_define_method(cUM, "prep_timeout", UM_prep_timeout, 1);
|
|
211
|
-
// rb_define_method(cUM, "prep_write", UM_prep_write, 1);
|
|
212
|
-
|
|
213
|
-
// rb_define_method(cUM, "submit", UM_submit, 0);
|
|
214
|
-
// rb_define_method(cUM, "wait_for_completion", UM_wait_for_completion, 0);
|
|
215
|
-
// rb_define_method(cUM, "process_completions", UM_process_completions, -1);
|
|
216
|
-
// rb_define_method(cUM, "process_completions_loop", UM_process_completions_loop, 0);
|
|
217
|
-
|
|
218
|
-
// SYM_accept = MAKE_SYM("accept");
|
|
219
|
-
// SYM_block = MAKE_SYM("block");
|
|
220
|
-
// SYM_buffer = MAKE_SYM("buffer");
|
|
221
|
-
// SYM_buffer_group = MAKE_SYM("buffer_group");
|
|
222
|
-
// SYM_buffer_offset = MAKE_SYM("buffer_offset");
|
|
223
|
-
// SYM_close = MAKE_SYM("close");
|
|
224
|
-
// SYM_count = MAKE_SYM("count");
|
|
225
|
-
// SYM_emit = MAKE_SYM("emit");
|
|
226
|
-
// SYM_fd = MAKE_SYM("fd");
|
|
227
|
-
// SYM_id = MAKE_SYM("id");
|
|
228
|
-
// SYM_interval = MAKE_SYM("interval");
|
|
229
|
-
// SYM_len = MAKE_SYM("len");
|
|
230
|
-
// SYM_link = MAKE_SYM("link");
|
|
231
|
-
// SYM_multishot = MAKE_SYM("multishot");
|
|
232
|
-
// SYM_op = MAKE_SYM("op");
|
|
233
|
-
// SYM_read = MAKE_SYM("read");
|
|
234
|
-
// SYM_result = MAKE_SYM("result");
|
|
235
|
-
// SYM_signal = MAKE_SYM("signal");
|
|
236
|
-
// SYM_size = MAKE_SYM("size");
|
|
237
|
-
// SYM_spec_data = MAKE_SYM("spec_data");
|
|
238
|
-
// SYM_stop = MAKE_SYM("stop");
|
|
239
|
-
// SYM_timeout = MAKE_SYM("timeout");
|
|
240
|
-
// SYM_utf8 = MAKE_SYM("utf8");
|
|
241
|
-
// SYM_write = MAKE_SYM("write");
|
|
221
|
+
rb_define_method(cUM, "socket", UM_socket, 4);
|
|
222
|
+
rb_define_method(cUM, "connect", UM_connect, 3);
|
|
223
|
+
rb_define_method(cUM, "send", UM_send, 4);
|
|
224
|
+
rb_define_method(cUM, "recv", UM_recv, 4);
|
|
225
|
+
rb_define_method(cUM, "bind", UM_bind, 3);
|
|
226
|
+
rb_define_method(cUM, "listen", UM_listen, 2);
|
|
227
|
+
|
|
228
|
+
um_define_net_constants(cUM);
|
|
242
229
|
}
|
data/ext/um/um_const.c
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
#include "ruby.h"
|
|
2
|
+
#include <arpa/inet.h>
|
|
3
|
+
#include <sys/types.h>
|
|
4
|
+
#include <sys/socket.h>
|
|
5
|
+
#include <netinet/in.h>
|
|
6
|
+
#include <netinet/tcp.h>
|
|
7
|
+
#include <netinet/udp.h>
|
|
8
|
+
#include <netdb.h>
|
|
9
|
+
#include <net/if.h>
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
#define DEF_CONST_INT(mod, v) rb_define_const(mod, #v, INT2NUM(v))
|
|
13
|
+
|
|
14
|
+
void um_define_net_constants(VALUE mod) {
|
|
15
|
+
DEF_CONST_INT(mod, SOCK_STREAM);
|
|
16
|
+
DEF_CONST_INT(mod, SOCK_DGRAM);
|
|
17
|
+
DEF_CONST_INT(mod, SOCK_RAW);
|
|
18
|
+
DEF_CONST_INT(mod, SOCK_RDM);
|
|
19
|
+
DEF_CONST_INT(mod, SOCK_SEQPACKET);
|
|
20
|
+
DEF_CONST_INT(mod, SOCK_PACKET);
|
|
21
|
+
DEF_CONST_INT(mod, SOCK_CLOEXEC);
|
|
22
|
+
|
|
23
|
+
DEF_CONST_INT(mod, AF_UNSPEC);
|
|
24
|
+
DEF_CONST_INT(mod, PF_UNSPEC);
|
|
25
|
+
DEF_CONST_INT(mod, AF_INET);
|
|
26
|
+
DEF_CONST_INT(mod, PF_INET);
|
|
27
|
+
DEF_CONST_INT(mod, AF_INET6);
|
|
28
|
+
DEF_CONST_INT(mod, PF_INET6);
|
|
29
|
+
DEF_CONST_INT(mod, AF_UNIX);
|
|
30
|
+
DEF_CONST_INT(mod, PF_UNIX);
|
|
31
|
+
DEF_CONST_INT(mod, AF_LOCAL);
|
|
32
|
+
DEF_CONST_INT(mod, PF_LOCAL);
|
|
33
|
+
DEF_CONST_INT(mod, AF_ROUTE);
|
|
34
|
+
DEF_CONST_INT(mod, PF_ROUTE);
|
|
35
|
+
DEF_CONST_INT(mod, AF_MAX);
|
|
36
|
+
DEF_CONST_INT(mod, PF_MAX);
|
|
37
|
+
|
|
38
|
+
DEF_CONST_INT(mod, MSG_OOB);
|
|
39
|
+
DEF_CONST_INT(mod, MSG_PEEK);
|
|
40
|
+
DEF_CONST_INT(mod, MSG_DONTROUTE);
|
|
41
|
+
DEF_CONST_INT(mod, MSG_WAITALL);
|
|
42
|
+
DEF_CONST_INT(mod, MSG_DONTWAIT);
|
|
43
|
+
DEF_CONST_INT(mod, MSG_MORE);
|
|
44
|
+
|
|
45
|
+
DEF_CONST_INT(mod, SOL_SOCKET);
|
|
46
|
+
DEF_CONST_INT(mod, SOL_IP);
|
|
47
|
+
|
|
48
|
+
DEF_CONST_INT(mod, IPPROTO_IP);
|
|
49
|
+
DEF_CONST_INT(mod, IPPROTO_ICMP);
|
|
50
|
+
DEF_CONST_INT(mod, IPPROTO_IGMP);
|
|
51
|
+
DEF_CONST_INT(mod, IPPROTO_TCP);
|
|
52
|
+
DEF_CONST_INT(mod, IPPROTO_EGP);
|
|
53
|
+
DEF_CONST_INT(mod, IPPROTO_PUP);
|
|
54
|
+
DEF_CONST_INT(mod, IPPROTO_UDP);
|
|
55
|
+
DEF_CONST_INT(mod, IPPROTO_IDP);
|
|
56
|
+
DEF_CONST_INT(mod, IPPROTO_IPV6);
|
|
57
|
+
DEF_CONST_INT(mod, IPPROTO_NONE);
|
|
58
|
+
DEF_CONST_INT(mod, IPPROTO_ROUTING);
|
|
59
|
+
DEF_CONST_INT(mod, IPPROTO_RAW);
|
|
60
|
+
DEF_CONST_INT(mod, IPPROTO_MAX);
|
|
61
|
+
|
|
62
|
+
DEF_CONST_INT(mod, INADDR_ANY);
|
|
63
|
+
DEF_CONST_INT(mod, INADDR_BROADCAST);
|
|
64
|
+
DEF_CONST_INT(mod, INADDR_LOOPBACK);
|
|
65
|
+
DEF_CONST_INT(mod, INADDR_NONE);
|
|
66
|
+
|
|
67
|
+
DEF_CONST_INT(mod, IP_OPTIONS);
|
|
68
|
+
DEF_CONST_INT(mod, IP_HDRINCL);
|
|
69
|
+
DEF_CONST_INT(mod, IP_TOS);
|
|
70
|
+
DEF_CONST_INT(mod, IP_TTL);
|
|
71
|
+
DEF_CONST_INT(mod, IP_RECVOPTS);
|
|
72
|
+
DEF_CONST_INT(mod, IP_MINTTL);
|
|
73
|
+
DEF_CONST_INT(mod, IP_RECVTTL);
|
|
74
|
+
|
|
75
|
+
DEF_CONST_INT(mod, SO_DEBUG);
|
|
76
|
+
DEF_CONST_INT(mod, SO_REUSEADDR);
|
|
77
|
+
DEF_CONST_INT(mod, SO_REUSEPORT);
|
|
78
|
+
DEF_CONST_INT(mod, SO_TYPE);
|
|
79
|
+
DEF_CONST_INT(mod, SO_ERROR);
|
|
80
|
+
DEF_CONST_INT(mod, SO_DONTROUTE);
|
|
81
|
+
DEF_CONST_INT(mod, SO_BROADCAST);
|
|
82
|
+
DEF_CONST_INT(mod, SO_SNDBUF);
|
|
83
|
+
DEF_CONST_INT(mod, SO_RCVBUF);
|
|
84
|
+
DEF_CONST_INT(mod, SO_SNDBUFFORCE);
|
|
85
|
+
DEF_CONST_INT(mod, SO_RCVBUFFORCE);
|
|
86
|
+
DEF_CONST_INT(mod, SO_KEEPALIVE);
|
|
87
|
+
DEF_CONST_INT(mod, SO_OOBINLINE);
|
|
88
|
+
DEF_CONST_INT(mod, SO_PRIORITY);
|
|
89
|
+
DEF_CONST_INT(mod, SO_LINGER);
|
|
90
|
+
DEF_CONST_INT(mod, SO_PASSCRED);
|
|
91
|
+
DEF_CONST_INT(mod, SO_PEERCRED);
|
|
92
|
+
DEF_CONST_INT(mod, SO_RCVLOWAT);
|
|
93
|
+
DEF_CONST_INT(mod, SO_SNDLOWAT);
|
|
94
|
+
DEF_CONST_INT(mod, SO_RCVTIMEO);
|
|
95
|
+
DEF_CONST_INT(mod, SO_SNDTIMEO);
|
|
96
|
+
DEF_CONST_INT(mod, SO_ACCEPTCONN);
|
|
97
|
+
DEF_CONST_INT(mod, SO_PEERNAME);
|
|
98
|
+
DEF_CONST_INT(mod, SO_TIMESTAMP);
|
|
99
|
+
DEF_CONST_INT(mod, SO_MARK);
|
|
100
|
+
DEF_CONST_INT(mod, SO_PROTOCOL);
|
|
101
|
+
DEF_CONST_INT(mod, SO_DOMAIN);
|
|
102
|
+
DEF_CONST_INT(mod, SO_PEEK_OFF);
|
|
103
|
+
DEF_CONST_INT(mod, SO_BUSY_POLL);
|
|
104
|
+
|
|
105
|
+
DEF_CONST_INT(mod, TCP_NODELAY);
|
|
106
|
+
DEF_CONST_INT(mod, TCP_MAXSEG);
|
|
107
|
+
DEF_CONST_INT(mod, TCP_CORK);
|
|
108
|
+
DEF_CONST_INT(mod, TCP_DEFER_ACCEPT);
|
|
109
|
+
DEF_CONST_INT(mod, TCP_INFO);
|
|
110
|
+
DEF_CONST_INT(mod, TCP_KEEPCNT);
|
|
111
|
+
DEF_CONST_INT(mod, TCP_KEEPIDLE);
|
|
112
|
+
DEF_CONST_INT(mod, TCP_KEEPINTVL);
|
|
113
|
+
DEF_CONST_INT(mod, TCP_LINGER2);
|
|
114
|
+
DEF_CONST_INT(mod, TCP_MD5SIG);
|
|
115
|
+
DEF_CONST_INT(mod, TCP_QUICKACK);
|
|
116
|
+
DEF_CONST_INT(mod, TCP_SYNCNT);
|
|
117
|
+
DEF_CONST_INT(mod, TCP_WINDOW_CLAMP);
|
|
118
|
+
DEF_CONST_INT(mod, TCP_FASTOPEN);
|
|
119
|
+
DEF_CONST_INT(mod, TCP_CONGESTION);
|
|
120
|
+
DEF_CONST_INT(mod, TCP_COOKIE_TRANSACTIONS);
|
|
121
|
+
DEF_CONST_INT(mod, TCP_QUEUE_SEQ);
|
|
122
|
+
DEF_CONST_INT(mod, TCP_REPAIR);
|
|
123
|
+
DEF_CONST_INT(mod, TCP_REPAIR_OPTIONS);
|
|
124
|
+
DEF_CONST_INT(mod, TCP_REPAIR_QUEUE);
|
|
125
|
+
DEF_CONST_INT(mod, TCP_THIN_LINEAR_TIMEOUTS);
|
|
126
|
+
DEF_CONST_INT(mod, TCP_TIMESTAMP);
|
|
127
|
+
DEF_CONST_INT(mod, TCP_USER_TIMEOUT);
|
|
128
|
+
|
|
129
|
+
DEF_CONST_INT(mod, UDP_CORK);
|
|
130
|
+
|
|
131
|
+
DEF_CONST_INT(mod, AI_PASSIVE);
|
|
132
|
+
DEF_CONST_INT(mod, AI_CANONNAME);
|
|
133
|
+
DEF_CONST_INT(mod, AI_NUMERICHOST);
|
|
134
|
+
DEF_CONST_INT(mod, AI_NUMERICSERV);
|
|
135
|
+
DEF_CONST_INT(mod, AI_ALL);
|
|
136
|
+
DEF_CONST_INT(mod, AI_ADDRCONFIG);
|
|
137
|
+
DEF_CONST_INT(mod, AI_V4MAPPED);
|
|
138
|
+
|
|
139
|
+
DEF_CONST_INT(mod, NI_MAXHOST);
|
|
140
|
+
DEF_CONST_INT(mod, NI_MAXSERV);
|
|
141
|
+
DEF_CONST_INT(mod, NI_NOFQDN);
|
|
142
|
+
DEF_CONST_INT(mod, NI_NUMERICHOST);
|
|
143
|
+
DEF_CONST_INT(mod, NI_NAMEREQD);
|
|
144
|
+
DEF_CONST_INT(mod, NI_NUMERICSERV);
|
|
145
|
+
DEF_CONST_INT(mod, NI_DGRAM);
|
|
146
|
+
|
|
147
|
+
DEF_CONST_INT(mod, SHUT_RD);
|
|
148
|
+
DEF_CONST_INT(mod, SHUT_WR);
|
|
149
|
+
DEF_CONST_INT(mod, SHUT_RDWR);
|
|
150
|
+
|
|
151
|
+
DEF_CONST_INT(mod, IPV6_JOIN_GROUP);
|
|
152
|
+
DEF_CONST_INT(mod, IPV6_LEAVE_GROUP);
|
|
153
|
+
DEF_CONST_INT(mod, IPV6_MULTICAST_HOPS);
|
|
154
|
+
DEF_CONST_INT(mod, IPV6_MULTICAST_IF);
|
|
155
|
+
DEF_CONST_INT(mod, IPV6_MULTICAST_LOOP);
|
|
156
|
+
DEF_CONST_INT(mod, IPV6_UNICAST_HOPS);
|
|
157
|
+
DEF_CONST_INT(mod, IPV6_V6ONLY);
|
|
158
|
+
DEF_CONST_INT(mod, IPV6_CHECKSUM);
|
|
159
|
+
DEF_CONST_INT(mod, IPV6_DONTFRAG);
|
|
160
|
+
DEF_CONST_INT(mod, IPV6_DSTOPTS);
|
|
161
|
+
DEF_CONST_INT(mod, IPV6_HOPLIMIT);
|
|
162
|
+
DEF_CONST_INT(mod, IPV6_HOPOPTS);
|
|
163
|
+
DEF_CONST_INT(mod, IPV6_NEXTHOP);
|
|
164
|
+
DEF_CONST_INT(mod, IPV6_PATHMTU);
|
|
165
|
+
DEF_CONST_INT(mod, IPV6_PKTINFO);
|
|
166
|
+
DEF_CONST_INT(mod, IPV6_RECVDSTOPTS);
|
|
167
|
+
DEF_CONST_INT(mod, IPV6_RECVHOPLIMIT);
|
|
168
|
+
DEF_CONST_INT(mod, IPV6_RECVHOPOPTS);
|
|
169
|
+
DEF_CONST_INT(mod, IPV6_RECVPKTINFO);
|
|
170
|
+
DEF_CONST_INT(mod, IPV6_RECVRTHDR);
|
|
171
|
+
DEF_CONST_INT(mod, IPV6_RECVTCLASS);
|
|
172
|
+
DEF_CONST_INT(mod, IPV6_RTHDR);
|
|
173
|
+
DEF_CONST_INT(mod, IPV6_RTHDRDSTOPTS);
|
|
174
|
+
DEF_CONST_INT(mod, IPV6_RTHDR_TYPE_0);
|
|
175
|
+
DEF_CONST_INT(mod, IPV6_RECVPATHMTU);
|
|
176
|
+
DEF_CONST_INT(mod, IPV6_TCLASS);
|
|
177
|
+
|
|
178
|
+
DEF_CONST_INT(mod, INET_ADDRSTRLEN);
|
|
179
|
+
DEF_CONST_INT(mod, INET6_ADDRSTRLEN);
|
|
180
|
+
|
|
181
|
+
DEF_CONST_INT(mod, IF_NAMESIZE);
|
|
182
|
+
|
|
183
|
+
DEF_CONST_INT(mod, SOMAXCONN);
|
|
184
|
+
}
|
data/ext/um/um_op.c
CHANGED
|
@@ -13,10 +13,10 @@ inline struct um_result_entry *um_result_checkout(struct um *machine) {
|
|
|
13
13
|
|
|
14
14
|
inline void um_result_checkin(struct um *machine, struct um_result_entry *entry) {
|
|
15
15
|
entry->next = machine->result_freelist;
|
|
16
|
-
machine->result_freelist = entry;
|
|
16
|
+
machine->result_freelist = entry;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
inline void um_op_result_cleanup(struct um *machine, struct um_op *op) {
|
|
19
|
+
inline void um_op_result_cleanup(struct um *machine, struct um_op *op) {
|
|
20
20
|
struct um_result_entry *entry = op->results_head;
|
|
21
21
|
while (entry) {
|
|
22
22
|
struct um_result_entry *next = entry->next;
|
|
@@ -26,7 +26,7 @@ inline void um_op_result_cleanup(struct um *machine, struct um_op *op) {
|
|
|
26
26
|
op->results_head = op->results_tail = NULL;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
inline void um_op_result_push(struct um *machine, struct um_op *op,
|
|
29
|
+
inline void um_op_result_push(struct um *machine, struct um_op *op, __s32 result, __u32 flags) {
|
|
30
30
|
struct um_result_entry *entry = um_result_checkout(machine);
|
|
31
31
|
entry->next = 0;
|
|
32
32
|
entry->result = result;
|
|
@@ -40,7 +40,7 @@ inline void um_op_result_push(struct um *machine, struct um_op *op, int result,
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
inline int um_op_result_shift(struct um *machine, struct um_op *op,
|
|
43
|
+
inline int um_op_result_shift(struct um *machine, struct um_op *op, __s32 *result, __u32 *flags) {
|
|
44
44
|
if (!op->results_head) return 0;
|
|
45
45
|
|
|
46
46
|
struct um_result_entry *entry = op->results_head;
|
|
@@ -61,23 +61,20 @@ inline void um_op_clear(struct um_op *op) {
|
|
|
61
61
|
inline struct um_op *um_op_checkout(struct um *machine) {
|
|
62
62
|
machine->pending_count++;
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
struct um_op *op = machine->op_freelist;
|
|
65
|
+
if (op)
|
|
66
66
|
machine->op_freelist = op->next;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
67
|
+
else
|
|
68
|
+
op = malloc(sizeof(struct um_op));
|
|
70
69
|
|
|
71
|
-
struct um_op *op = malloc(sizeof(struct um_op));
|
|
72
70
|
um_op_clear(op);
|
|
73
71
|
return op;
|
|
74
72
|
}
|
|
75
73
|
|
|
76
74
|
inline void um_op_checkin(struct um *machine, struct um_op *op) {
|
|
77
|
-
um_op_result_cleanup(machine, op);
|
|
78
|
-
|
|
79
75
|
machine->pending_count--;
|
|
80
76
|
|
|
77
|
+
um_op_result_cleanup(machine, op);
|
|
81
78
|
op->next = machine->op_freelist;
|
|
82
79
|
machine->op_freelist = op;
|
|
83
80
|
}
|
|
@@ -124,7 +121,7 @@ inline struct um_op *um_runqueue_shift(struct um *machine) {
|
|
|
124
121
|
|
|
125
122
|
op->prev = NULL;
|
|
126
123
|
if (!op->next) {
|
|
127
|
-
machine->runqueue_head = machine->runqueue_tail = NULL;
|
|
124
|
+
machine->runqueue_head = machine->runqueue_tail = NULL;
|
|
128
125
|
}
|
|
129
126
|
else {
|
|
130
127
|
machine->runqueue_head = op->next;
|
data/ext/um/um_utils.c
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#include "um.h"
|
|
2
|
+
#include <sys/mman.h>
|
|
3
|
+
#include <stdlib.h>
|
|
2
4
|
|
|
3
5
|
inline struct __kernel_timespec um_double_to_timespec(double value) {
|
|
4
6
|
double integral;
|
|
@@ -46,13 +48,56 @@ static inline void adjust_read_buffer_len(VALUE buffer, int result, int ofs) {
|
|
|
46
48
|
rb_str_set_len(buffer, len + (unsigned)ofs);
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
inline void um_update_read_buffer(struct um *machine, VALUE buffer, int buffer_offset,
|
|
51
|
+
inline void um_update_read_buffer(struct um *machine, VALUE buffer, int buffer_offset, __s32 result, __u32 flags) {
|
|
50
52
|
if (!result) return;
|
|
51
53
|
|
|
52
54
|
adjust_read_buffer_len(buffer, result, buffer_offset);
|
|
53
55
|
}
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
int um_setup_buffer_ring(struct um *machine, unsigned size, unsigned count) {
|
|
58
|
+
if (machine->buffer_ring_count == BUFFER_RING_MAX_COUNT)
|
|
59
|
+
rb_raise(rb_eRuntimeError, "Cannot setup more than BUFFER_RING_MAX_COUNT buffer rings");
|
|
60
|
+
|
|
61
|
+
struct buf_ring_descriptor *desc = machine->buffer_rings + machine->buffer_ring_count;
|
|
62
|
+
desc->buf_count = count;
|
|
63
|
+
desc->buf_size = size;
|
|
64
|
+
|
|
65
|
+
desc->br_size = sizeof(struct io_uring_buf) * desc->buf_count;
|
|
66
|
+
void *mapped = mmap(
|
|
67
|
+
NULL, desc->br_size, PROT_READ | PROT_WRITE,
|
|
68
|
+
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0
|
|
69
|
+
);
|
|
70
|
+
if (mapped == MAP_FAILED)
|
|
71
|
+
rb_raise(rb_eRuntimeError, "Failed to allocate buffer ring");
|
|
72
|
+
|
|
73
|
+
desc->br = (struct io_uring_buf_ring *)mapped;
|
|
74
|
+
io_uring_buf_ring_init(desc->br);
|
|
75
|
+
|
|
76
|
+
unsigned bg_id = machine->buffer_ring_count;
|
|
77
|
+
int ret;
|
|
78
|
+
desc->br = io_uring_setup_buf_ring(&machine->ring, count, bg_id, 0, &ret);
|
|
79
|
+
if (!desc->br) {
|
|
80
|
+
munmap(desc->br, desc->br_size);
|
|
81
|
+
rb_syserr_fail(ret, strerror(ret));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (posix_memalign(&desc->buf_base, 4096, desc->buf_count * desc->buf_size)) {
|
|
85
|
+
io_uring_free_buf_ring(&machine->ring, desc->br, desc->buf_count, bg_id);
|
|
86
|
+
rb_raise(rb_eRuntimeError, "Failed to allocate buffers");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
desc->buf_mask = io_uring_buf_ring_mask(desc->buf_count);
|
|
90
|
+
void *ptr = desc->buf_base;
|
|
91
|
+
for (unsigned i = 0; i < desc->buf_count; i++) {
|
|
92
|
+
io_uring_buf_ring_add(desc->br, ptr, desc->buf_size, i, desc->buf_mask, i);
|
|
93
|
+
ptr += desc->buf_size;
|
|
94
|
+
}
|
|
95
|
+
io_uring_buf_ring_advance(desc->br, desc->buf_count);
|
|
96
|
+
machine->buffer_ring_count++;
|
|
97
|
+
return bg_id;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
inline VALUE um_get_string_from_buffer_ring(struct um *machine, int bgid, __s32 result, __u32 flags) {
|
|
56
101
|
if (!result) return Qnil;
|
|
57
102
|
|
|
58
103
|
unsigned buf_idx = flags >> IORING_CQE_BUFFER_SHIFT;
|
|
@@ -64,7 +109,7 @@ inline VALUE get_string_from_buffer_ring(struct um *machine, int bgid, int resul
|
|
|
64
109
|
|
|
65
110
|
// add buffer back to buffer ring
|
|
66
111
|
io_uring_buf_ring_add(
|
|
67
|
-
desc->br, src, desc->buf_size, buf_idx,
|
|
112
|
+
desc->br, src, desc->buf_size, buf_idx, desc->buf_mask, 0
|
|
68
113
|
);
|
|
69
114
|
io_uring_buf_ring_advance(desc->br, 1);
|
|
70
115
|
|
data/lib/uringmachine/version.rb
CHANGED
data/lib/uringmachine.rb
CHANGED
|
@@ -3,3 +3,15 @@
|
|
|
3
3
|
require_relative './um_ext'
|
|
4
4
|
|
|
5
5
|
UM = UringMachine
|
|
6
|
+
|
|
7
|
+
class UringMachine
|
|
8
|
+
def spin(value = nil, &block)
|
|
9
|
+
Fiber.new do |resume_value|
|
|
10
|
+
block.(resume_value)
|
|
11
|
+
rescue Exception => e
|
|
12
|
+
raise RuntimeError, "Unhandled fiber exception: #{e.inspect}"
|
|
13
|
+
ensure
|
|
14
|
+
self.yield
|
|
15
|
+
end.tap { |f| schedule(f, value) }
|
|
16
|
+
end
|
|
17
|
+
end
|
data/test/helper.rb
CHANGED