uringmachine 0.2 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -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 +340 -53
- data/ext/um/um.h +33 -11
- data/ext/um/um_class.c +101 -119
- data/ext/um/um_const.c +184 -0
- data/ext/um/um_op.c +39 -18
- 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 +13 -12
- data/test/test_um.rb +301 -3
- 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
|
|
@@ -14,7 +14,7 @@ static void UM_compact(void *ptr) {
|
|
14
14
|
}
|
15
15
|
|
16
16
|
static void UM_free(void *ptr) {
|
17
|
-
|
17
|
+
um_teardown((struct um *)ptr);
|
18
18
|
free(ptr);
|
19
19
|
}
|
20
20
|
|
@@ -43,90 +43,16 @@ inline struct um *get_machine(VALUE self) {
|
|
43
43
|
|
44
44
|
VALUE UM_initialize(VALUE self) {
|
45
45
|
struct um *machine = RTYPEDDATA_DATA(self);
|
46
|
-
|
47
|
-
machine->ring_initialized = 0;
|
48
|
-
machine->unsubmitted_count = 0;
|
49
|
-
machine->buffer_ring_count = 0;
|
50
|
-
machine->pending_count = 0;
|
51
|
-
machine->runqueue_head = NULL;
|
52
|
-
machine->runqueue_tail = NULL;
|
53
|
-
machine->freelist_head = NULL;
|
54
|
-
|
55
|
-
unsigned prepared_limit = 4096;
|
56
|
-
int flags = 0;
|
57
|
-
#ifdef HAVE_IORING_SETUP_SUBMIT_ALL
|
58
|
-
flags |= IORING_SETUP_SUBMIT_ALL;
|
59
|
-
#endif
|
60
|
-
#ifdef HAVE_IORING_SETUP_COOP_TASKRUN
|
61
|
-
flags |= IORING_SETUP_COOP_TASKRUN;
|
62
|
-
#endif
|
63
|
-
|
64
|
-
while (1) {
|
65
|
-
int ret = io_uring_queue_init(prepared_limit, &machine->ring, flags);
|
66
|
-
if (likely(!ret)) break;
|
67
|
-
|
68
|
-
// if ENOMEM is returned, try with half as much entries
|
69
|
-
if (unlikely(ret == -ENOMEM && prepared_limit > 64))
|
70
|
-
prepared_limit = prepared_limit / 2;
|
71
|
-
else
|
72
|
-
rb_syserr_fail(-ret, strerror(-ret));
|
73
|
-
}
|
74
|
-
machine->ring_initialized = 1;
|
75
|
-
|
46
|
+
um_setup(machine);
|
76
47
|
return self;
|
77
48
|
}
|
78
49
|
|
79
50
|
VALUE UM_setup_buffer_ring(VALUE self, VALUE size, VALUE count) {
|
80
51
|
struct um *machine = get_machine(self);
|
81
|
-
|
82
|
-
|
83
|
-
rb_raise(rb_eRuntimeError, "Cannot setup more than BUFFER_RING_MAX_COUNT buffer rings");
|
84
|
-
|
85
|
-
struct buf_ring_descriptor *desc = machine->buffer_rings + machine->buffer_ring_count;
|
86
|
-
desc->buf_count = NUM2UINT(count);
|
87
|
-
desc->buf_size = NUM2UINT(size);
|
88
|
-
|
89
|
-
desc->br_size = sizeof(struct io_uring_buf) * desc->buf_count;
|
90
|
-
void *mapped = mmap(
|
91
|
-
NULL, desc->br_size, PROT_READ | PROT_WRITE,
|
92
|
-
MAP_ANONYMOUS | MAP_PRIVATE, 0, 0
|
93
|
-
);
|
94
|
-
if (mapped == MAP_FAILED)
|
95
|
-
rb_raise(rb_eRuntimeError, "Failed to allocate buffer ring");
|
96
|
-
|
97
|
-
desc->br = (struct io_uring_buf_ring *)mapped;
|
98
|
-
io_uring_buf_ring_init(desc->br);
|
99
|
-
|
100
|
-
unsigned bg_id = machine->buffer_ring_count;
|
101
|
-
struct io_uring_buf_reg reg = {
|
102
|
-
.ring_addr = (unsigned long)desc->br,
|
103
|
-
.ring_entries = desc->buf_count,
|
104
|
-
.bgid = bg_id
|
105
|
-
};
|
106
|
-
int ret = io_uring_register_buf_ring(&machine->ring, ®, 0);
|
107
|
-
if (ret) {
|
108
|
-
munmap(desc->br, desc->br_size);
|
109
|
-
rb_syserr_fail(-ret, strerror(-ret));
|
110
|
-
}
|
111
|
-
|
112
|
-
desc->buf_base = malloc(desc->buf_count * desc->buf_size);
|
113
|
-
if (!desc->buf_base) {
|
114
|
-
io_uring_free_buf_ring(&machine->ring, desc->br, desc->buf_count, bg_id);
|
115
|
-
rb_raise(rb_eRuntimeError, "Failed to allocate buffers");
|
116
|
-
}
|
117
|
-
|
118
|
-
int mask = io_uring_buf_ring_mask(desc->buf_count);
|
119
|
-
for (unsigned i = 0; i < desc->buf_count; i++) {
|
120
|
-
io_uring_buf_ring_add(
|
121
|
-
desc->br, desc->buf_base + i * desc->buf_size, desc->buf_size,
|
122
|
-
i, mask, i);
|
123
|
-
}
|
124
|
-
io_uring_buf_ring_advance(desc->br, desc->buf_count);
|
125
|
-
machine->buffer_ring_count++;
|
126
|
-
return UINT2NUM(bg_id);
|
52
|
+
int bgid = um_setup_buffer_ring(machine, NUM2UINT(size), NUM2UINT(count));
|
53
|
+
return INT2NUM(bgid);
|
127
54
|
}
|
128
55
|
|
129
|
-
|
130
56
|
VALUE UM_pending_count(VALUE self) {
|
131
57
|
struct um *machine = get_machine(self);
|
132
58
|
return INT2FIX(machine->pending_count);
|
@@ -185,6 +111,89 @@ VALUE UM_read_each(VALUE self, VALUE fd, VALUE bgid) {
|
|
185
111
|
return um_read_each(machine, NUM2INT(fd), NUM2INT(bgid));
|
186
112
|
}
|
187
113
|
|
114
|
+
VALUE UM_write(int argc, VALUE *argv, VALUE self) {
|
115
|
+
struct um *machine = get_machine(self);
|
116
|
+
VALUE fd;
|
117
|
+
VALUE buffer;
|
118
|
+
VALUE len;
|
119
|
+
rb_scan_args(argc, argv, "21", &fd, &buffer, &len);
|
120
|
+
|
121
|
+
int bytes = NIL_P(len) ? RSTRING_LEN(buffer) : NUM2INT(len);
|
122
|
+
return um_write(machine, NUM2INT(fd), buffer, bytes);
|
123
|
+
}
|
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
|
+
|
130
|
+
VALUE UM_accept(VALUE self, VALUE fd) {
|
131
|
+
struct um *machine = get_machine(self);
|
132
|
+
return um_accept(machine, NUM2INT(fd));
|
133
|
+
}
|
134
|
+
|
135
|
+
VALUE UM_accept_each(VALUE self, VALUE fd) {
|
136
|
+
struct um *machine = get_machine(self);
|
137
|
+
return um_accept_each(machine, NUM2INT(fd));
|
138
|
+
}
|
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
|
+
|
188
197
|
void Init_UM(void) {
|
189
198
|
rb_ext_ractor_safe(true);
|
190
199
|
|
@@ -204,44 +213,17 @@ void Init_UM(void) {
|
|
204
213
|
rb_define_method(cUM, "sleep", UM_sleep, 1);
|
205
214
|
rb_define_method(cUM, "read", UM_read, -1);
|
206
215
|
rb_define_method(cUM, "read_each", UM_read_each, 2);
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
// rb_define_method(cUM, "process_completions", UM_process_completions, -1);
|
221
|
-
// rb_define_method(cUM, "process_completions_loop", UM_process_completions_loop, 0);
|
222
|
-
|
223
|
-
// SYM_accept = MAKE_SYM("accept");
|
224
|
-
// SYM_block = MAKE_SYM("block");
|
225
|
-
// SYM_buffer = MAKE_SYM("buffer");
|
226
|
-
// SYM_buffer_group = MAKE_SYM("buffer_group");
|
227
|
-
// SYM_buffer_offset = MAKE_SYM("buffer_offset");
|
228
|
-
// SYM_close = MAKE_SYM("close");
|
229
|
-
// SYM_count = MAKE_SYM("count");
|
230
|
-
// SYM_emit = MAKE_SYM("emit");
|
231
|
-
// SYM_fd = MAKE_SYM("fd");
|
232
|
-
// SYM_id = MAKE_SYM("id");
|
233
|
-
// SYM_interval = MAKE_SYM("interval");
|
234
|
-
// SYM_len = MAKE_SYM("len");
|
235
|
-
// SYM_link = MAKE_SYM("link");
|
236
|
-
// SYM_multishot = MAKE_SYM("multishot");
|
237
|
-
// SYM_op = MAKE_SYM("op");
|
238
|
-
// SYM_read = MAKE_SYM("read");
|
239
|
-
// SYM_result = MAKE_SYM("result");
|
240
|
-
// SYM_signal = MAKE_SYM("signal");
|
241
|
-
// SYM_size = MAKE_SYM("size");
|
242
|
-
// SYM_spec_data = MAKE_SYM("spec_data");
|
243
|
-
// SYM_stop = MAKE_SYM("stop");
|
244
|
-
// SYM_timeout = MAKE_SYM("timeout");
|
245
|
-
// SYM_utf8 = MAKE_SYM("utf8");
|
246
|
-
// SYM_write = MAKE_SYM("write");
|
216
|
+
rb_define_method(cUM, "write", UM_write, -1);
|
217
|
+
rb_define_method(cUM, "close", UM_close, 1);
|
218
|
+
|
219
|
+
rb_define_method(cUM, "accept", UM_accept, 1);
|
220
|
+
rb_define_method(cUM, "accept_each", UM_accept_each, 1);
|
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);
|
247
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
@@ -1,17 +1,33 @@
|
|
1
1
|
#include "um.h"
|
2
2
|
|
3
|
+
inline struct um_result_entry *um_result_checkout(struct um *machine) {
|
4
|
+
if (machine->result_freelist) {
|
5
|
+
struct um_result_entry *entry = machine->result_freelist;
|
6
|
+
machine->result_freelist = entry->next;
|
7
|
+
return entry;
|
8
|
+
}
|
9
|
+
|
10
|
+
struct um_result_entry *entry = malloc(sizeof(struct um_result_entry));
|
11
|
+
return entry;
|
12
|
+
}
|
13
|
+
|
14
|
+
inline void um_result_checkin(struct um *machine, struct um_result_entry *entry) {
|
15
|
+
entry->next = machine->result_freelist;
|
16
|
+
machine->result_freelist = entry;
|
17
|
+
}
|
18
|
+
|
3
19
|
inline void um_op_result_cleanup(struct um *machine, struct um_op *op) {
|
4
20
|
struct um_result_entry *entry = op->results_head;
|
5
21
|
while (entry) {
|
6
22
|
struct um_result_entry *next = entry->next;
|
7
|
-
|
23
|
+
um_result_checkin(machine, entry);
|
8
24
|
entry = next;
|
9
25
|
}
|
10
26
|
op->results_head = op->results_tail = NULL;
|
11
27
|
}
|
12
28
|
|
13
|
-
inline void um_op_result_push(struct um *machine, struct um_op *op,
|
14
|
-
struct um_result_entry *entry =
|
29
|
+
inline void um_op_result_push(struct um *machine, struct um_op *op, __s32 result, __u32 flags) {
|
30
|
+
struct um_result_entry *entry = um_result_checkout(machine);
|
15
31
|
entry->next = 0;
|
16
32
|
entry->result = result;
|
17
33
|
entry->flags = flags;
|
@@ -24,7 +40,7 @@ inline void um_op_result_push(struct um *machine, struct um_op *op, int result,
|
|
24
40
|
}
|
25
41
|
}
|
26
42
|
|
27
|
-
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) {
|
28
44
|
if (!op->results_head) return 0;
|
29
45
|
|
30
46
|
struct um_result_entry *entry = op->results_head;
|
@@ -33,7 +49,7 @@ inline int um_op_result_shift(struct um *machine, struct um_op *op, int *result,
|
|
33
49
|
op->results_head = entry->next;
|
34
50
|
if (!op->results_head)
|
35
51
|
op->results_tail = NULL;
|
36
|
-
|
52
|
+
um_result_checkin(machine, entry);
|
37
53
|
return 1;
|
38
54
|
}
|
39
55
|
|
@@ -45,25 +61,22 @@ inline void um_op_clear(struct um_op *op) {
|
|
45
61
|
inline struct um_op *um_op_checkout(struct um *machine) {
|
46
62
|
machine->pending_count++;
|
47
63
|
|
48
|
-
|
49
|
-
|
50
|
-
machine->
|
51
|
-
|
52
|
-
|
53
|
-
}
|
64
|
+
struct um_op *op = machine->op_freelist;
|
65
|
+
if (op)
|
66
|
+
machine->op_freelist = op->next;
|
67
|
+
else
|
68
|
+
op = malloc(sizeof(struct um_op));
|
54
69
|
|
55
|
-
struct um_op *op = malloc(sizeof(struct um_op));
|
56
70
|
um_op_clear(op);
|
57
71
|
return op;
|
58
72
|
}
|
59
73
|
|
60
74
|
inline void um_op_checkin(struct um *machine, struct um_op *op) {
|
61
|
-
um_op_result_cleanup(machine, op);
|
62
|
-
|
63
75
|
machine->pending_count--;
|
64
76
|
|
65
|
-
op
|
66
|
-
|
77
|
+
um_op_result_cleanup(machine, op);
|
78
|
+
op->next = machine->op_freelist;
|
79
|
+
machine->op_freelist = op;
|
67
80
|
}
|
68
81
|
|
69
82
|
inline struct um_op *um_runqueue_find_by_fiber(struct um *machine, VALUE fiber) {
|
@@ -108,7 +121,7 @@ inline struct um_op *um_runqueue_shift(struct um *machine) {
|
|
108
121
|
|
109
122
|
op->prev = NULL;
|
110
123
|
if (!op->next) {
|
111
|
-
machine->runqueue_head = machine->runqueue_tail = NULL;
|
124
|
+
machine->runqueue_head = machine->runqueue_tail = NULL;
|
112
125
|
}
|
113
126
|
else {
|
114
127
|
machine->runqueue_head = op->next;
|
@@ -117,7 +130,7 @@ inline struct um_op *um_runqueue_shift(struct um *machine) {
|
|
117
130
|
return op;
|
118
131
|
}
|
119
132
|
|
120
|
-
inline void
|
133
|
+
inline void um_free_op_linked_list(struct um *machine, struct um_op *op) {
|
121
134
|
while (op) {
|
122
135
|
struct um_op *next = op->next;
|
123
136
|
um_op_result_cleanup(machine, op);
|
@@ -125,3 +138,11 @@ inline void um_free_linked_list(struct um *machine, struct um_op *op) {
|
|
125
138
|
op = next;
|
126
139
|
}
|
127
140
|
}
|
141
|
+
|
142
|
+
inline void um_free_result_linked_list(struct um *machine, struct um_result_entry *entry) {
|
143
|
+
while (entry) {
|
144
|
+
struct um_result_entry *next = entry->next;
|
145
|
+
free(entry);
|
146
|
+
entry = next;
|
147
|
+
}
|
148
|
+
}
|
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
|