uringmachine 0.19 → 0.20.0
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 +15 -0
- data/TODO.md +40 -0
- data/examples/bm_fileno.rb +33 -0
- data/examples/bm_mutex.rb +85 -0
- data/examples/bm_mutex_single.rb +33 -0
- data/examples/bm_queue.rb +27 -28
- data/examples/bm_send.rb +2 -5
- data/examples/bm_snooze.rb +20 -42
- data/examples/fiber_scheduler_demo.rb +15 -51
- data/examples/fiber_scheduler_fork.rb +24 -0
- data/examples/nc_ssl.rb +71 -0
- data/ext/um/extconf.rb +5 -15
- data/ext/um/um.c +73 -42
- data/ext/um/um.h +21 -11
- data/ext/um/um_async_op_class.c +2 -2
- data/ext/um/um_buffer.c +1 -1
- data/ext/um/um_class.c +94 -23
- data/ext/um/um_const.c +51 -3
- data/ext/um/um_mutex_class.c +1 -1
- data/ext/um/um_queue_class.c +1 -1
- data/ext/um/um_stream.c +5 -5
- data/ext/um/um_stream_class.c +3 -0
- data/ext/um/um_sync.c +22 -27
- data/ext/um/um_utils.c +59 -19
- data/grant-2025/journal.md +229 -0
- data/grant-2025/tasks.md +66 -0
- data/lib/uringmachine/fiber_scheduler.rb +180 -48
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +6 -0
- data/test/test_fiber_scheduler.rb +138 -0
- data/test/test_stream.rb +2 -2
- data/test/test_um.rb +451 -33
- data/vendor/liburing/.github/workflows/ci.yml +94 -1
- data/vendor/liburing/.github/workflows/test_build.c +9 -0
- data/vendor/liburing/configure +27 -0
- data/vendor/liburing/examples/Makefile +6 -0
- data/vendor/liburing/examples/helpers.c +8 -0
- data/vendor/liburing/examples/helpers.h +5 -0
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/Makefile +9 -3
- data/vendor/liburing/src/include/liburing/barrier.h +11 -5
- data/vendor/liburing/src/include/liburing/io_uring/query.h +41 -0
- data/vendor/liburing/src/include/liburing/io_uring.h +50 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +16 -4
- data/vendor/liburing/src/include/liburing.h +445 -121
- data/vendor/liburing/src/liburing-ffi.map +15 -0
- data/vendor/liburing/src/liburing.map +8 -0
- data/vendor/liburing/src/sanitize.c +4 -1
- data/vendor/liburing/src/setup.c +7 -4
- data/vendor/liburing/test/232c93d07b74.c +4 -16
- data/vendor/liburing/test/Makefile +15 -1
- data/vendor/liburing/test/accept.c +2 -13
- data/vendor/liburing/test/conn-unreach.c +132 -0
- data/vendor/liburing/test/fd-pass.c +32 -7
- data/vendor/liburing/test/fdinfo.c +39 -12
- data/vendor/liburing/test/fifo-futex-poll.c +114 -0
- data/vendor/liburing/test/fifo-nonblock-read.c +1 -12
- data/vendor/liburing/test/futex.c +1 -1
- data/vendor/liburing/test/helpers.c +99 -2
- data/vendor/liburing/test/helpers.h +9 -0
- data/vendor/liburing/test/io_uring_passthrough.c +6 -12
- data/vendor/liburing/test/mock_file.c +379 -0
- data/vendor/liburing/test/mock_file.h +47 -0
- data/vendor/liburing/test/nop.c +2 -2
- data/vendor/liburing/test/nop32-overflow.c +150 -0
- data/vendor/liburing/test/nop32.c +126 -0
- data/vendor/liburing/test/pipe.c +166 -0
- data/vendor/liburing/test/poll-race-mshot.c +13 -1
- data/vendor/liburing/test/recv-mshot-fair.c +81 -34
- data/vendor/liburing/test/recvsend_bundle.c +1 -1
- data/vendor/liburing/test/resize-rings.c +2 -0
- data/vendor/liburing/test/ring-query.c +322 -0
- data/vendor/liburing/test/ringbuf-loop.c +87 -0
- data/vendor/liburing/test/runtests.sh +2 -2
- data/vendor/liburing/test/send-zerocopy.c +43 -5
- data/vendor/liburing/test/send_recv.c +102 -32
- data/vendor/liburing/test/shutdown.c +2 -12
- data/vendor/liburing/test/socket-nb.c +3 -14
- data/vendor/liburing/test/socket-rw-eagain.c +2 -12
- data/vendor/liburing/test/socket-rw-offset.c +2 -12
- data/vendor/liburing/test/socket-rw.c +2 -12
- data/vendor/liburing/test/sqe-mixed-bad-wrap.c +87 -0
- data/vendor/liburing/test/sqe-mixed-nop.c +82 -0
- data/vendor/liburing/test/sqe-mixed-uring_cmd.c +153 -0
- data/vendor/liburing/test/timestamp.c +56 -19
- data/vendor/liburing/test/vec-regbuf.c +2 -4
- data/vendor/liburing/test/wq-aff.c +7 -0
- metadata +24 -2
|
@@ -15,13 +15,15 @@
|
|
|
15
15
|
#include "liburing.h"
|
|
16
16
|
#include "helpers.h"
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
#define MAX_MSG 4096
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
static unsigned long str[MAX_MSG / sizeof(unsigned long)];
|
|
21
21
|
|
|
22
22
|
#define PORT 10202
|
|
23
23
|
#define HOST "127.0.0.1"
|
|
24
24
|
|
|
25
|
+
static int no_send_vec;
|
|
26
|
+
|
|
25
27
|
static int recv_prep(struct io_uring *ring, struct iovec *iov, int *sock,
|
|
26
28
|
int registerfiles, int async, int provide)
|
|
27
29
|
{
|
|
@@ -86,7 +88,8 @@ err:
|
|
|
86
88
|
static int do_recv(struct io_uring *ring, struct iovec *iov, int enobufs)
|
|
87
89
|
{
|
|
88
90
|
struct io_uring_cqe *cqe;
|
|
89
|
-
|
|
91
|
+
unsigned long *ptr;
|
|
92
|
+
int i, ret;
|
|
90
93
|
|
|
91
94
|
ret = io_uring_wait_cqe(ring, &cqe);
|
|
92
95
|
if (ret) {
|
|
@@ -109,14 +112,16 @@ static int do_recv(struct io_uring *ring, struct iovec *iov, int enobufs)
|
|
|
109
112
|
goto err;
|
|
110
113
|
}
|
|
111
114
|
|
|
112
|
-
if (cqe->res
|
|
113
|
-
fprintf(stderr, "got wrong length: %d/%d\n", cqe->res,
|
|
114
|
-
(int) strlen(str) + 1);
|
|
115
|
+
if (cqe->res != MAX_MSG) {
|
|
116
|
+
fprintf(stderr, "got wrong length: %d/%d\n", cqe->res, MAX_MSG);
|
|
115
117
|
goto err;
|
|
116
118
|
}
|
|
117
119
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
+
ptr = iov->iov_base;
|
|
121
|
+
for (i = 0; i < MAX_MSG / sizeof(unsigned long); i++) {
|
|
122
|
+
if (ptr[i] == str[i])
|
|
123
|
+
continue;
|
|
124
|
+
fprintf(stderr, "data mismatch at %d: %lu\n", i, ptr[i]);
|
|
120
125
|
goto err;
|
|
121
126
|
}
|
|
122
127
|
|
|
@@ -183,13 +188,10 @@ err:
|
|
|
183
188
|
return (void *)(intptr_t)ret;
|
|
184
189
|
}
|
|
185
190
|
|
|
186
|
-
static int do_send(
|
|
191
|
+
static int do_send(int async, int vec, int big_vec)
|
|
187
192
|
{
|
|
188
193
|
struct sockaddr_in saddr;
|
|
189
|
-
struct iovec
|
|
190
|
-
.iov_base = str,
|
|
191
|
-
.iov_len = sizeof(str),
|
|
192
|
-
};
|
|
194
|
+
struct iovec vecs[32];
|
|
193
195
|
struct io_uring ring;
|
|
194
196
|
struct io_uring_cqe *cqe;
|
|
195
197
|
struct io_uring_sqe *sqe;
|
|
@@ -218,8 +220,37 @@ static int do_send(void)
|
|
|
218
220
|
goto err;
|
|
219
221
|
}
|
|
220
222
|
|
|
223
|
+
retry:
|
|
221
224
|
sqe = io_uring_get_sqe(&ring);
|
|
222
|
-
|
|
225
|
+
if (vec) {
|
|
226
|
+
size_t total = MAX_MSG;
|
|
227
|
+
unsigned long *ptr = str;
|
|
228
|
+
int i, nvecs;
|
|
229
|
+
|
|
230
|
+
if (!big_vec) {
|
|
231
|
+
vecs[0].iov_base = str;
|
|
232
|
+
vecs[0].iov_len = MAX_MSG / 2;
|
|
233
|
+
vecs[1].iov_base = &str[256];
|
|
234
|
+
vecs[1].iov_len = MAX_MSG / 2;
|
|
235
|
+
nvecs = 2;
|
|
236
|
+
} else {
|
|
237
|
+
total /= 32;
|
|
238
|
+
|
|
239
|
+
for (i = 0; i < 32; i++) {
|
|
240
|
+
vecs[i].iov_base = ptr;
|
|
241
|
+
vecs[i].iov_len = total;
|
|
242
|
+
ptr += total / sizeof(unsigned long);
|
|
243
|
+
}
|
|
244
|
+
nvecs = 32;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
io_uring_prep_send(sqe, sockfd, vecs, nvecs, 0);
|
|
248
|
+
sqe->ioprio = (1U << 5);
|
|
249
|
+
} else {
|
|
250
|
+
io_uring_prep_send(sqe, sockfd, str, sizeof(str), 0);
|
|
251
|
+
}
|
|
252
|
+
if (async)
|
|
253
|
+
sqe->flags |= IOSQE_ASYNC;
|
|
223
254
|
sqe->user_data = 1;
|
|
224
255
|
|
|
225
256
|
ret = io_uring_submit(&ring);
|
|
@@ -230,10 +261,16 @@ static int do_send(void)
|
|
|
230
261
|
|
|
231
262
|
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
232
263
|
if (cqe->res == -EINVAL) {
|
|
264
|
+
if (vec) {
|
|
265
|
+
vec = 0;
|
|
266
|
+
no_send_vec = 1;
|
|
267
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
268
|
+
goto retry;
|
|
269
|
+
}
|
|
233
270
|
fprintf(stdout, "send not supported, skipping\n");
|
|
234
271
|
goto err;
|
|
235
272
|
}
|
|
236
|
-
if (cqe->res !=
|
|
273
|
+
if (cqe->res != sizeof(str)) {
|
|
237
274
|
fprintf(stderr, "failed cqe: %d\n", cqe->res);
|
|
238
275
|
goto err;
|
|
239
276
|
}
|
|
@@ -249,7 +286,8 @@ err2:
|
|
|
249
286
|
return 1;
|
|
250
287
|
}
|
|
251
288
|
|
|
252
|
-
static int test(int use_sqthread, int regfiles, int async, int provide
|
|
289
|
+
static int test(int use_sqthread, int regfiles, int async, int provide, int vec,
|
|
290
|
+
int big_vec)
|
|
253
291
|
{
|
|
254
292
|
pthread_mutexattr_t attr;
|
|
255
293
|
pthread_t recv_thread;
|
|
@@ -257,6 +295,9 @@ static int test(int use_sqthread, int regfiles, int async, int provide)
|
|
|
257
295
|
int ret;
|
|
258
296
|
void *retval;
|
|
259
297
|
|
|
298
|
+
if (vec && no_send_vec)
|
|
299
|
+
return T_EXIT_SKIP;
|
|
300
|
+
|
|
260
301
|
pthread_mutexattr_init(&attr);
|
|
261
302
|
pthread_mutexattr_setpshared(&attr, 1);
|
|
262
303
|
pthread_mutex_init(&rd.mutex, &attr);
|
|
@@ -274,7 +315,7 @@ static int test(int use_sqthread, int regfiles, int async, int provide)
|
|
|
274
315
|
}
|
|
275
316
|
|
|
276
317
|
pthread_mutex_lock(&rd.mutex);
|
|
277
|
-
do_send();
|
|
318
|
+
do_send(async, vec, big_vec);
|
|
278
319
|
pthread_join(recv_thread, &retval);
|
|
279
320
|
return (intptr_t)retval;
|
|
280
321
|
}
|
|
@@ -325,10 +366,13 @@ static int test_invalid(void)
|
|
|
325
366
|
|
|
326
367
|
int main(int argc, char *argv[])
|
|
327
368
|
{
|
|
328
|
-
int ret;
|
|
369
|
+
int i, ret;
|
|
329
370
|
|
|
330
371
|
if (argc > 1)
|
|
331
|
-
return
|
|
372
|
+
return T_EXIT_SKIP;
|
|
373
|
+
|
|
374
|
+
for (i = 0; i < MAX_MSG / sizeof(unsigned long); i++)
|
|
375
|
+
str[i] = i + 1;
|
|
332
376
|
|
|
333
377
|
ret = test_invalid();
|
|
334
378
|
if (ret) {
|
|
@@ -336,77 +380,103 @@ int main(int argc, char *argv[])
|
|
|
336
380
|
return ret;
|
|
337
381
|
}
|
|
338
382
|
|
|
339
|
-
ret = test(0, 0, 1, 1);
|
|
383
|
+
ret = test(0, 0, 1, 1, 0, 0);
|
|
340
384
|
if (ret) {
|
|
341
385
|
fprintf(stderr, "test sqthread=0 1 1 failed\n");
|
|
342
386
|
return ret;
|
|
343
387
|
}
|
|
344
388
|
|
|
345
|
-
ret = test(1, 1, 1, 1);
|
|
389
|
+
ret = test(1, 1, 1, 1, 0, 0);
|
|
346
390
|
if (ret) {
|
|
347
391
|
fprintf(stderr, "test sqthread=1 reg=1 1 1 failed\n");
|
|
348
392
|
return ret;
|
|
349
393
|
}
|
|
350
394
|
|
|
351
|
-
ret = test(1, 0, 1, 1);
|
|
395
|
+
ret = test(1, 0, 1, 1, 0, 0);
|
|
352
396
|
if (ret) {
|
|
353
397
|
fprintf(stderr, "test sqthread=1 reg=0 1 1 failed\n");
|
|
354
398
|
return ret;
|
|
355
399
|
}
|
|
356
400
|
|
|
357
|
-
ret = test(0, 0, 0, 1);
|
|
401
|
+
ret = test(0, 0, 0, 1, 0, 0);
|
|
358
402
|
if (ret) {
|
|
359
403
|
fprintf(stderr, "test sqthread=0 0 1 failed\n");
|
|
360
404
|
return ret;
|
|
361
405
|
}
|
|
362
406
|
|
|
363
|
-
ret = test(1, 1, 0, 1);
|
|
407
|
+
ret = test(1, 1, 0, 1, 0, 0);
|
|
364
408
|
if (ret) {
|
|
365
409
|
fprintf(stderr, "test sqthread=1 reg=1 0 1 failed\n");
|
|
366
410
|
return ret;
|
|
367
411
|
}
|
|
368
412
|
|
|
369
|
-
ret = test(1, 0, 0, 1);
|
|
413
|
+
ret = test(1, 0, 0, 1, 0, 0);
|
|
370
414
|
if (ret) {
|
|
371
415
|
fprintf(stderr, "test sqthread=1 reg=0 0 1 failed\n");
|
|
372
416
|
return ret;
|
|
373
417
|
}
|
|
374
418
|
|
|
375
|
-
ret = test(0, 0, 1, 0);
|
|
419
|
+
ret = test(0, 0, 1, 0, 0, 0);
|
|
376
420
|
if (ret) {
|
|
377
421
|
fprintf(stderr, "test sqthread=0 0 1 failed\n");
|
|
378
422
|
return ret;
|
|
379
423
|
}
|
|
380
424
|
|
|
381
|
-
ret = test(1, 1, 1, 0);
|
|
425
|
+
ret = test(1, 1, 1, 0, 0, 0);
|
|
382
426
|
if (ret) {
|
|
383
427
|
fprintf(stderr, "test sqthread=1 reg=1 1 0 failed\n");
|
|
384
428
|
return ret;
|
|
385
429
|
}
|
|
386
430
|
|
|
387
|
-
ret = test(1, 0, 1, 0);
|
|
431
|
+
ret = test(1, 0, 1, 0, 0, 0);
|
|
388
432
|
if (ret) {
|
|
389
433
|
fprintf(stderr, "test sqthread=1 reg=0 1 0 failed\n");
|
|
390
434
|
return ret;
|
|
391
435
|
}
|
|
392
436
|
|
|
393
|
-
ret = test(0, 0, 0, 0);
|
|
437
|
+
ret = test(0, 0, 0, 0, 0, 0);
|
|
394
438
|
if (ret) {
|
|
395
439
|
fprintf(stderr, "test sqthread=0 0 0 failed\n");
|
|
396
440
|
return ret;
|
|
397
441
|
}
|
|
398
442
|
|
|
399
|
-
ret = test(1, 1, 0, 0);
|
|
443
|
+
ret = test(1, 1, 0, 0, 0, 0);
|
|
400
444
|
if (ret) {
|
|
401
445
|
fprintf(stderr, "test sqthread=1 reg=1 0 0 failed\n");
|
|
402
446
|
return ret;
|
|
403
447
|
}
|
|
404
448
|
|
|
405
|
-
ret = test(1, 0, 0, 0);
|
|
449
|
+
ret = test(1, 0, 0, 0, 0, 0);
|
|
406
450
|
if (ret) {
|
|
407
451
|
fprintf(stderr, "test sqthread=1 reg=0 0 0 failed\n");
|
|
408
452
|
return ret;
|
|
409
453
|
}
|
|
410
454
|
|
|
411
|
-
|
|
455
|
+
ret = test(0, 0, 0, 0, 1, 0);
|
|
456
|
+
if (ret) {
|
|
457
|
+
fprintf(stderr, "test small vec sync failed\n");
|
|
458
|
+
return ret;
|
|
459
|
+
}
|
|
460
|
+
if (no_send_vec)
|
|
461
|
+
return T_EXIT_PASS;
|
|
462
|
+
|
|
463
|
+
ret = test(0, 0, 1, 0, 1, 0);
|
|
464
|
+
if (ret) {
|
|
465
|
+
fprintf(stderr, "test small vec async failed\n");
|
|
466
|
+
return ret;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
ret = test(0, 0, 0, 0, 1, 1);
|
|
470
|
+
if (ret) {
|
|
471
|
+
fprintf(stderr, "test big vec sync failed\n");
|
|
472
|
+
return ret;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
ret = test(0, 0, 1, 0, 1, 1);
|
|
476
|
+
if (ret) {
|
|
477
|
+
fprintf(stderr, "test big vec async failed\n");
|
|
478
|
+
return ret;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return T_EXIT_PASS;
|
|
412
482
|
}
|
|
@@ -58,22 +58,12 @@ int main(int argc, char *argv[])
|
|
|
58
58
|
ret = setsockopt(p_fd[1], IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
|
|
59
59
|
assert(ret != -1);
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
assert(flags != -1);
|
|
63
|
-
|
|
64
|
-
flags |= O_NONBLOCK;
|
|
65
|
-
ret = fcntl(p_fd[1], F_SETFL, flags);
|
|
66
|
-
assert(ret != -1);
|
|
61
|
+
t_set_nonblock(p_fd[1]);
|
|
67
62
|
|
|
68
63
|
ret = connect(p_fd[1], (struct sockaddr*)&addr, sizeof(addr));
|
|
69
64
|
assert(ret == -1);
|
|
70
65
|
|
|
71
|
-
|
|
72
|
-
assert(flags != -1);
|
|
73
|
-
|
|
74
|
-
flags &= ~O_NONBLOCK;
|
|
75
|
-
ret = fcntl(p_fd[1], F_SETFL, flags);
|
|
76
|
-
assert(ret != -1);
|
|
66
|
+
t_clear_nonblock(p_fd[1]);
|
|
77
67
|
|
|
78
68
|
p_fd[0] = accept(recv_s0, NULL, NULL);
|
|
79
69
|
assert(p_fd[0] != -1);
|
|
@@ -51,12 +51,7 @@ static int test(int o_nonblock, int msg_dontwait)
|
|
|
51
51
|
ret = setsockopt(p_fd[1], IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
|
|
52
52
|
assert(ret != -1);
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
assert(flags != -1);
|
|
56
|
-
|
|
57
|
-
flags |= O_NONBLOCK;
|
|
58
|
-
ret = fcntl(p_fd[1], F_SETFL, flags);
|
|
59
|
-
assert(ret != -1);
|
|
54
|
+
t_set_nonblock(p_fd[1]);
|
|
60
55
|
|
|
61
56
|
ret = connect(p_fd[1], (struct sockaddr *) &addr, sizeof(addr));
|
|
62
57
|
assert(ret == -1);
|
|
@@ -64,14 +59,8 @@ static int test(int o_nonblock, int msg_dontwait)
|
|
|
64
59
|
p_fd[0] = accept(recv_s0, NULL, NULL);
|
|
65
60
|
assert(p_fd[0] != -1);
|
|
66
61
|
|
|
67
|
-
if (o_nonblock)
|
|
68
|
-
|
|
69
|
-
assert(flags != -1);
|
|
70
|
-
|
|
71
|
-
flags |= O_NONBLOCK;
|
|
72
|
-
ret = fcntl(p_fd[0], F_SETFL, flags);
|
|
73
|
-
assert(ret != -1);
|
|
74
|
-
}
|
|
62
|
+
if (o_nonblock)
|
|
63
|
+
t_set_nonblock(p_fd[0]);
|
|
75
64
|
|
|
76
65
|
while (1) {
|
|
77
66
|
int32_t code;
|
|
@@ -53,12 +53,7 @@ int main(int argc, char *argv[])
|
|
|
53
53
|
ret = setsockopt(p_fd[1], IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
|
|
54
54
|
assert(ret != -1);
|
|
55
55
|
|
|
56
|
-
|
|
57
|
-
assert(flags != -1);
|
|
58
|
-
|
|
59
|
-
flags |= O_NONBLOCK;
|
|
60
|
-
ret = fcntl(p_fd[1], F_SETFL, flags);
|
|
61
|
-
assert(ret != -1);
|
|
56
|
+
t_set_nonblock(p_fd[1]);
|
|
62
57
|
|
|
63
58
|
ret = connect(p_fd[1], (struct sockaddr*)&addr, sizeof(addr));
|
|
64
59
|
assert(ret == -1);
|
|
@@ -66,12 +61,7 @@ int main(int argc, char *argv[])
|
|
|
66
61
|
p_fd[0] = accept(recv_s0, NULL, NULL);
|
|
67
62
|
assert(p_fd[0] != -1);
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
assert(flags != -1);
|
|
71
|
-
|
|
72
|
-
flags |= O_NONBLOCK;
|
|
73
|
-
ret = fcntl(p_fd[0], F_SETFL, flags);
|
|
74
|
-
assert(ret != -1);
|
|
64
|
+
t_set_nonblock(p_fd[0]);
|
|
75
65
|
|
|
76
66
|
while (1) {
|
|
77
67
|
int32_t code;
|
|
@@ -56,22 +56,12 @@ int main(int argc, char *argv[])
|
|
|
56
56
|
ret = setsockopt(p_fd[1], IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
|
|
57
57
|
assert(ret != -1);
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
assert(flags != -1);
|
|
61
|
-
|
|
62
|
-
flags |= O_NONBLOCK;
|
|
63
|
-
ret = fcntl(p_fd[1], F_SETFL, flags);
|
|
64
|
-
assert(ret != -1);
|
|
59
|
+
t_set_nonblock(p_fd[1]);
|
|
65
60
|
|
|
66
61
|
ret = connect(p_fd[1], (struct sockaddr*)&addr, sizeof(addr));
|
|
67
62
|
assert(ret == -1);
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
assert(flags != -1);
|
|
71
|
-
|
|
72
|
-
flags &= ~O_NONBLOCK;
|
|
73
|
-
ret = fcntl(p_fd[1], F_SETFL, flags);
|
|
74
|
-
assert(ret != -1);
|
|
64
|
+
t_clear_nonblock(p_fd[1]);
|
|
75
65
|
|
|
76
66
|
p_fd[0] = accept(recv_s0, NULL, NULL);
|
|
77
67
|
assert(p_fd[0] != -1);
|
|
@@ -56,22 +56,12 @@ int main(int argc, char *argv[])
|
|
|
56
56
|
ret = setsockopt(p_fd[1], IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
|
|
57
57
|
assert(ret != -1);
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
assert(flags != -1);
|
|
61
|
-
|
|
62
|
-
flags |= O_NONBLOCK;
|
|
63
|
-
ret = fcntl(p_fd[1], F_SETFL, flags);
|
|
64
|
-
assert(ret != -1);
|
|
59
|
+
t_set_nonblock(p_fd[1]);
|
|
65
60
|
|
|
66
61
|
ret = connect(p_fd[1], (struct sockaddr*)&addr, sizeof(addr));
|
|
67
62
|
assert(ret == -1);
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
assert(flags != -1);
|
|
71
|
-
|
|
72
|
-
flags &= ~O_NONBLOCK;
|
|
73
|
-
ret = fcntl(p_fd[1], F_SETFL, flags);
|
|
74
|
-
assert(ret != -1);
|
|
64
|
+
t_clear_nonblock(p_fd[1]);
|
|
75
65
|
|
|
76
66
|
p_fd[0] = accept(recv_s0, NULL, NULL);
|
|
77
67
|
assert(p_fd[0] != -1);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: run various nop tests
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
#include <stdio.h>
|
|
7
|
+
|
|
8
|
+
#include "liburing.h"
|
|
9
|
+
#include "helpers.h"
|
|
10
|
+
#include "test.h"
|
|
11
|
+
|
|
12
|
+
static int seq;
|
|
13
|
+
|
|
14
|
+
static int test_single_nop(struct io_uring *ring, bool should_fail)
|
|
15
|
+
{
|
|
16
|
+
struct io_uring_cqe *cqe;
|
|
17
|
+
struct io_uring_sqe *sqe;
|
|
18
|
+
int ret;
|
|
19
|
+
|
|
20
|
+
sqe = io_uring_get_sqe(ring);
|
|
21
|
+
if (!sqe) {
|
|
22
|
+
fprintf(stderr, "get sqe failed\n");
|
|
23
|
+
return T_EXIT_FAIL;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (should_fail)
|
|
27
|
+
io_uring_prep_nop128(sqe);
|
|
28
|
+
else
|
|
29
|
+
io_uring_prep_nop(sqe);
|
|
30
|
+
sqe->user_data = ++seq;
|
|
31
|
+
|
|
32
|
+
ret = io_uring_submit(ring);
|
|
33
|
+
if (ret <= 0) {
|
|
34
|
+
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
|
35
|
+
return T_EXIT_FAIL;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
|
39
|
+
if (ret < 0) {
|
|
40
|
+
fprintf(stderr, "wait completion %d\n", ret);
|
|
41
|
+
} else if (should_fail && cqe->res == 0) {
|
|
42
|
+
fprintf(stderr, "Unexpected success\n");
|
|
43
|
+
} else if (!should_fail && cqe->res != 0) {
|
|
44
|
+
fprintf(stderr, "Completion error:%d\n", cqe->res);
|
|
45
|
+
} else if (cqe->res == 0 && cqe->user_data != seq) {
|
|
46
|
+
fprintf(stderr, "Unexpected user_data: %ld\n", (long) cqe->user_data);
|
|
47
|
+
} else {
|
|
48
|
+
io_uring_cqe_seen(ring, cqe);
|
|
49
|
+
return T_EXIT_PASS;
|
|
50
|
+
}
|
|
51
|
+
return T_EXIT_FAIL;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
int main(int argc, char *argv[])
|
|
55
|
+
{
|
|
56
|
+
struct io_uring ring;
|
|
57
|
+
int ret, i;
|
|
58
|
+
|
|
59
|
+
if (argc > 1)
|
|
60
|
+
return T_EXIT_SKIP;
|
|
61
|
+
|
|
62
|
+
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SQE_MIXED);
|
|
63
|
+
if (ret) {
|
|
64
|
+
if (ret == -EINVAL)
|
|
65
|
+
return T_EXIT_SKIP;
|
|
66
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
|
67
|
+
return T_EXIT_FAIL;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* prime the sq to the last entry before wrapping */
|
|
71
|
+
for (i = 0; i < 7; i++) {
|
|
72
|
+
ret = test_single_nop(&ring, false);
|
|
73
|
+
if (ret != T_EXIT_PASS)
|
|
74
|
+
goto done;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* inserting a 128b sqe in the last entry should fail */
|
|
78
|
+
ret = test_single_nop(&ring, true);
|
|
79
|
+
if (ret != T_EXIT_PASS)
|
|
80
|
+
goto done;
|
|
81
|
+
|
|
82
|
+
/* proceeding from the bad wrap should succeed */
|
|
83
|
+
ret = test_single_nop(&ring, false);
|
|
84
|
+
done:
|
|
85
|
+
io_uring_queue_exit(&ring);
|
|
86
|
+
return ret;
|
|
87
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: run various nop tests
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
#include <stdio.h>
|
|
7
|
+
|
|
8
|
+
#include "liburing.h"
|
|
9
|
+
#include "helpers.h"
|
|
10
|
+
#include "test.h"
|
|
11
|
+
|
|
12
|
+
static int seq;
|
|
13
|
+
|
|
14
|
+
static int test_single_nop(struct io_uring *ring, bool sqe128)
|
|
15
|
+
{
|
|
16
|
+
struct io_uring_cqe *cqe;
|
|
17
|
+
struct io_uring_sqe *sqe;
|
|
18
|
+
int ret;
|
|
19
|
+
|
|
20
|
+
if (sqe128)
|
|
21
|
+
sqe = io_uring_get_sqe128(ring);
|
|
22
|
+
else
|
|
23
|
+
sqe = io_uring_get_sqe(ring);
|
|
24
|
+
|
|
25
|
+
if (!sqe) {
|
|
26
|
+
fprintf(stderr, "get sqe failed\n");
|
|
27
|
+
return T_EXIT_FAIL;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (sqe128)
|
|
31
|
+
io_uring_prep_nop128(sqe);
|
|
32
|
+
else
|
|
33
|
+
io_uring_prep_nop(sqe);
|
|
34
|
+
|
|
35
|
+
sqe->user_data = ++seq;
|
|
36
|
+
|
|
37
|
+
ret = io_uring_submit(ring);
|
|
38
|
+
if (ret <= 0) {
|
|
39
|
+
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
|
40
|
+
return T_EXIT_FAIL;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
|
44
|
+
if (ret < 0) {
|
|
45
|
+
fprintf(stderr, "wait completion %d\n", ret);
|
|
46
|
+
} else if (cqe->res != 0) {
|
|
47
|
+
fprintf(stderr, "Completion error:%d\n", cqe->res);
|
|
48
|
+
} else if (cqe->user_data != seq) {
|
|
49
|
+
fprintf(stderr, "Unexpected user_data: %ld\n", (long) cqe->user_data);
|
|
50
|
+
} else {
|
|
51
|
+
io_uring_cqe_seen(ring, cqe);
|
|
52
|
+
return T_EXIT_PASS;
|
|
53
|
+
}
|
|
54
|
+
return T_EXIT_FAIL;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
int main(int argc, char *argv[])
|
|
58
|
+
{
|
|
59
|
+
struct io_uring ring;
|
|
60
|
+
int ret, i;
|
|
61
|
+
|
|
62
|
+
if (argc > 1)
|
|
63
|
+
return T_EXIT_SKIP;
|
|
64
|
+
|
|
65
|
+
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SQE_MIXED);
|
|
66
|
+
if (ret) {
|
|
67
|
+
if (ret == -EINVAL)
|
|
68
|
+
return T_EXIT_SKIP;
|
|
69
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
|
70
|
+
return T_EXIT_FAIL;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* alternate big and little sqe's */
|
|
74
|
+
for (i = 0; i < 32; i++) {
|
|
75
|
+
ret = test_single_nop(&ring, i & 1);
|
|
76
|
+
if (ret != T_EXIT_PASS)
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
io_uring_queue_exit(&ring);
|
|
81
|
+
return ret;
|
|
82
|
+
}
|