| .. | .. |
|---|
| 62 | 62 | static int cfg_port = 8000; |
|---|
| 63 | 63 | static int cfg_runtime_ms = -1; |
|---|
| 64 | 64 | static bool cfg_poll; |
|---|
| 65 | +static int cfg_poll_loop_timeout_ms = 2000; |
|---|
| 65 | 66 | static bool cfg_segment; |
|---|
| 66 | 67 | static bool cfg_sendmmsg; |
|---|
| 67 | 68 | static bool cfg_tcp; |
|---|
| .. | .. |
|---|
| 235 | 236 | } |
|---|
| 236 | 237 | } |
|---|
| 237 | 238 | |
|---|
| 238 | | -static void flush_errqueue(int fd, const bool do_poll) |
|---|
| 239 | +static void flush_errqueue(int fd, const bool do_poll, |
|---|
| 240 | + unsigned long poll_timeout, const bool poll_err) |
|---|
| 239 | 241 | { |
|---|
| 240 | 242 | if (do_poll) { |
|---|
| 241 | 243 | struct pollfd fds = {0}; |
|---|
| 242 | 244 | int ret; |
|---|
| 243 | 245 | |
|---|
| 244 | 246 | fds.fd = fd; |
|---|
| 245 | | - ret = poll(&fds, 1, 500); |
|---|
| 247 | + ret = poll(&fds, 1, poll_timeout); |
|---|
| 246 | 248 | if (ret == 0) { |
|---|
| 247 | | - if (cfg_verbose) |
|---|
| 249 | + if ((cfg_verbose) && (poll_err)) |
|---|
| 248 | 250 | fprintf(stderr, "poll timeout\n"); |
|---|
| 249 | 251 | } else if (ret < 0) { |
|---|
| 250 | 252 | error(1, errno, "poll"); |
|---|
| .. | .. |
|---|
| 252 | 254 | } |
|---|
| 253 | 255 | |
|---|
| 254 | 256 | flush_errqueue_recv(fd); |
|---|
| 257 | +} |
|---|
| 258 | + |
|---|
| 259 | +static void flush_errqueue_retry(int fd, unsigned long num_sends) |
|---|
| 260 | +{ |
|---|
| 261 | + unsigned long tnow, tstop; |
|---|
| 262 | + bool first_try = true; |
|---|
| 263 | + |
|---|
| 264 | + tnow = gettimeofday_ms(); |
|---|
| 265 | + tstop = tnow + cfg_poll_loop_timeout_ms; |
|---|
| 266 | + do { |
|---|
| 267 | + flush_errqueue(fd, true, tstop - tnow, first_try); |
|---|
| 268 | + first_try = false; |
|---|
| 269 | + tnow = gettimeofday_ms(); |
|---|
| 270 | + } while ((stat_zcopies != num_sends) && (tnow < tstop)); |
|---|
| 255 | 271 | } |
|---|
| 256 | 272 | |
|---|
| 257 | 273 | static int send_tcp(int fd, char *data) |
|---|
| .. | .. |
|---|
| 413 | 429 | |
|---|
| 414 | 430 | static void usage(const char *filepath) |
|---|
| 415 | 431 | { |
|---|
| 416 | | - error(1, 0, "Usage: %s [-46acmHPtTuvz] [-C cpu] [-D dst ip] [-l secs] [-M messagenr] [-p port] [-s sendsize] [-S gsosize]", |
|---|
| 432 | + error(1, 0, "Usage: %s [-46acmHPtTuvz] [-C cpu] [-D dst ip] [-l secs] " |
|---|
| 433 | + "[-L secs] [-M messagenr] [-p port] [-s sendsize] [-S gsosize]", |
|---|
| 417 | 434 | filepath); |
|---|
| 418 | 435 | } |
|---|
| 419 | 436 | |
|---|
| .. | .. |
|---|
| 423 | 440 | int max_len, hdrlen; |
|---|
| 424 | 441 | int c; |
|---|
| 425 | 442 | |
|---|
| 426 | | - while ((c = getopt(argc, argv, "46acC:D:Hl:mM:p:s:PS:tTuvz")) != -1) { |
|---|
| 443 | + while ((c = getopt(argc, argv, "46acC:D:Hl:L:mM:p:s:PS:tTuvz")) != -1) { |
|---|
| 427 | 444 | switch (c) { |
|---|
| 428 | 445 | case '4': |
|---|
| 429 | 446 | if (cfg_family != PF_UNSPEC) |
|---|
| .. | .. |
|---|
| 451 | 468 | break; |
|---|
| 452 | 469 | case 'l': |
|---|
| 453 | 470 | cfg_runtime_ms = strtoul(optarg, NULL, 10) * 1000; |
|---|
| 471 | + break; |
|---|
| 472 | + case 'L': |
|---|
| 473 | + cfg_poll_loop_timeout_ms = strtoul(optarg, NULL, 10) * 1000; |
|---|
| 454 | 474 | break; |
|---|
| 455 | 475 | case 'm': |
|---|
| 456 | 476 | cfg_sendmmsg = true; |
|---|
| .. | .. |
|---|
| 490 | 510 | case 'z': |
|---|
| 491 | 511 | cfg_zerocopy = true; |
|---|
| 492 | 512 | break; |
|---|
| 513 | + default: |
|---|
| 514 | + exit(1); |
|---|
| 493 | 515 | } |
|---|
| 494 | 516 | } |
|---|
| 495 | 517 | |
|---|
| .. | .. |
|---|
| 677 | 699 | num_sends += send_udp(fd, buf[i]); |
|---|
| 678 | 700 | num_msgs++; |
|---|
| 679 | 701 | if ((cfg_zerocopy && ((num_msgs & 0xF) == 0)) || cfg_tx_tstamp) |
|---|
| 680 | | - flush_errqueue(fd, cfg_poll); |
|---|
| 702 | + flush_errqueue(fd, cfg_poll, 500, true); |
|---|
| 681 | 703 | |
|---|
| 682 | 704 | if (cfg_msg_nr && num_msgs >= cfg_msg_nr) |
|---|
| 683 | 705 | break; |
|---|
| .. | .. |
|---|
| 696 | 718 | } while (!interrupted && (cfg_runtime_ms == -1 || tnow < tstop)); |
|---|
| 697 | 719 | |
|---|
| 698 | 720 | if (cfg_zerocopy || cfg_tx_tstamp) |
|---|
| 699 | | - flush_errqueue(fd, true); |
|---|
| 721 | + flush_errqueue_retry(fd, num_sends); |
|---|
| 700 | 722 | |
|---|
| 701 | 723 | if (close(fd)) |
|---|
| 702 | 724 | error(1, errno, "close"); |
|---|