| 434 | } |
| 435 | |
| 436 | static int do_send(struct recv_data *rd) |
| 437 | { |
| 438 | struct sockaddr_in saddr; |
| 439 | struct io_uring ring; |
| 440 | unsigned long seq_buf[SEQ_SIZE], send_seq; |
| 441 | struct io_uring_params p = { }; |
| 442 | struct io_uring_buf_ring *br; |
| 443 | int sockfd, ret, len, i; |
| 444 | socklen_t optlen; |
| 445 | void *buf = NULL, *ptr; |
| 446 | |
| 447 | ret = io_uring_queue_init_params(16, &ring, &p); |
| 448 | if (ret) { |
| 449 | fprintf(stderr, "queue init failed: %d\n", ret); |
| 450 | return 1; |
| 451 | } |
| 452 | if (!(p.features & IORING_FEAT_RECVSEND_BUNDLE)) { |
| 453 | rd->abort = 1; |
| 454 | no_send_mshot = 1; |
| 455 | pthread_barrier_wait(&rd->connect); |
| 456 | return 0; |
| 457 | } |
| 458 | |
| 459 | if (posix_memalign(&buf, sysconf(_SC_PAGESIZE), MSG_SIZE * nr_msgs)) |
| 460 | return 1; |
| 461 | |
| 462 | if (!classic_buffers) { |
| 463 | br = io_uring_setup_buf_ring(&ring, nr_msgs, SEND_BGID, 0, &ret); |
| 464 | if (!br) { |
| 465 | if (ret == -EINVAL) { |
| 466 | fprintf(stderr, "einval on br setup\n"); |
| 467 | return 0; |
| 468 | } |
| 469 | fprintf(stderr, "failed setting up send ring %d\n", ret); |
| 470 | return 1; |
| 471 | } |
| 472 | |
| 473 | ptr = buf; |
| 474 | for (i = 0; i < nr_msgs; i++) { |
| 475 | io_uring_buf_ring_add(br, ptr, MSG_SIZE, i, nr_msgs - 1, i); |
| 476 | ptr += MSG_SIZE; |
| 477 | } |
| 478 | io_uring_buf_ring_advance(br, nr_msgs); |
| 479 | } else { |
| 480 | ret = provide_classic_buffers(&ring, buf, nr_msgs, SEND_BGID); |
| 481 | if (ret) { |
| 482 | fprintf(stderr, "failed providing classic buffers\n"); |
| 483 | return ret; |
| 484 | } |
| 485 | } |
| 486 | |
| 487 | memset(&saddr, 0, sizeof(saddr)); |
| 488 | saddr.sin_family = AF_INET; |
| 489 | saddr.sin_port = htons(use_port); |
| 490 | inet_pton(AF_INET, HOST, &saddr.sin_addr); |
| 491 | |
| 492 | if (use_tcp) |
| 493 | sockfd = socket(AF_INET, SOCK_STREAM, 0); |
no test coverage detected