diff options
| author | David M. Syzdek <david.syzdek@acsalaska.com> | 2022-07-21 21:39:44 -0800 |
|---|---|---|
| committer | David M. Syzdek <david.syzdek@acsalaska.com> | 2022-07-21 21:39:44 -0800 |
| commit | a3e409ac1d2f5dce8e4bde33ecf4a9911ffa2d3a (patch) | |
| tree | c7adcb7fe29dbc7e50c722537167c13ff3d0d72d | |
| parent | 12a8fecd97646895b404b7a73236a808b8a72c23 (diff) | |
| download | akcom-udpecho-a3e409ac1d2f5dce8e4bde33ecf4a9911ffa2d3a.tar.gz akcom-udpecho-a3e409ac1d2f5dce8e4bde33ecf4a9911ffa2d3a.tar.bz2 akcom-udpecho-a3e409ac1d2f5dce8e4bde33ecf4a9911ffa2d3a.tar.xz akcom-udpecho-a3e409ac1d2f5dce8e4bde33ecf4a9911ffa2d3a.zip | |
akcom-udpecho: refactoring my_loop()
| -rw-r--r-- | src/akcom-udpecho.c | 207 |
1 files changed, 134 insertions, 73 deletions
diff --git a/src/akcom-udpecho.c b/src/akcom-udpecho.c index f044f13..085f4ca 100644 --- a/src/akcom-udpecho.c +++ b/src/akcom-udpecho.c | |||
| @@ -103,13 +103,24 @@ | |||
| 103 | #define PACKAGE_VERSION "0.0" | 103 | #define PACKAGE_VERSION "0.0" |
| 104 | #endif | 104 | #endif |
| 105 | 105 | ||
| 106 | #define my_sec2msec( sec ) ( sec * 1000 ) | ||
| 106 | #define my_sec2usec( sec ) ( sec * 1000000 ) | 107 | #define my_sec2usec( sec ) ( sec * 1000000 ) |
| 107 | #define my_sec2nsec( sec ) ( sec * 1000000000 ) | 108 | #define my_sec2nsec( sec ) ( sec * 1000000000 ) |
| 108 | #define my_usec2sec( usec ) ( usec / 1000000 ) | 109 | |
| 110 | #define my_msec2sec( msec ) ( msec / 1000 ) | ||
| 111 | #define my_msec2usec( msec ) ( msec * 1000 ) | ||
| 112 | #define my_msec2nsec( msec ) ( msec * 1000000 ) | ||
| 113 | |||
| 114 | #define my_usec2sec( usec ) ( usec / 1000000 ) | ||
| 115 | #define my_usec2msec( usec ) ( usec / 1000 ) | ||
| 109 | #define my_usec2nsec( usec ) ( usec * 1000 ) | 116 | #define my_usec2nsec( usec ) ( usec * 1000 ) |
| 110 | #define my_nsec2sec( nsec ) ( nsec / 1000000000 ) | 117 | |
| 118 | #define my_nsec2sec( nsec ) ( nsec / 1000000000 ) | ||
| 119 | #define my_nsec2msec( nsec ) ( nsec / 1000000 ) | ||
| 111 | #define my_nsec2usec( nsec ) ( nsec / 1000 ) | 120 | #define my_nsec2usec( nsec ) ( nsec / 1000 ) |
| 112 | 121 | ||
| 122 | #define my_usec2msec_tenths( usec ) ((usec%1000)/100) | ||
| 123 | |||
| 113 | 124 | ||
| 114 | ///////////////// | 125 | ///////////////// |
| 115 | // // | 126 | // // |
| @@ -135,6 +146,7 @@ typedef struct udp_echo_plus | |||
| 135 | uint32_t reply_time; | 146 | uint32_t reply_time; |
| 136 | uint32_t failures; | 147 | uint32_t failures; |
| 137 | uint32_t iteration; | 148 | uint32_t iteration; |
| 149 | struct timespec send_time; | ||
| 138 | uint8_t bytes[]; | 150 | uint8_t bytes[]; |
| 139 | } echoplus_t; | 151 | } echoplus_t; |
| 140 | 152 | ||
| @@ -195,6 +207,12 @@ static void | |||
| 195 | int signum ); | 207 | int signum ); |
| 196 | 208 | ||
| 197 | 209 | ||
| 210 | extern uint64_t | ||
| 211 | my_timespec_delta( | ||
| 212 | struct timespec * ts1, | ||
| 213 | struct timespec * ts2, | ||
| 214 | struct timespec * delta ); | ||
| 215 | |||
| 198 | 216 | ||
| 199 | // display program usage | 217 | // display program usage |
| 200 | static void | 218 | static void |
| @@ -419,10 +437,10 @@ my_loop( | |||
| 419 | echoplus_t * sndbuff ) | 437 | echoplus_t * sndbuff ) |
| 420 | { | 438 | { |
| 421 | int rc; | 439 | int rc; |
| 422 | uint64_t epoch; | 440 | uint64_t pckt_time; |
| 423 | uint64_t epoch_adj; | 441 | uint64_t pckt_time_adj; |
| 424 | uint64_t epoch_max; | 442 | uint64_t epoch_usec; |
| 425 | uint64_t delay; | 443 | uint64_t pckt_delay; |
| 426 | uint32_t stats_sent; | 444 | uint32_t stats_sent; |
| 427 | uint32_t stats_rcvd; | 445 | uint32_t stats_rcvd; |
| 428 | uint64_t stats_max; | 446 | uint64_t stats_max; |
| @@ -433,6 +451,7 @@ my_loop( | |||
| 433 | uint64_t stats_avg_adj; | 451 | uint64_t stats_avg_adj; |
| 434 | ssize_t size; | 452 | ssize_t size; |
| 435 | struct pollfd fds[2]; | 453 | struct pollfd fds[2]; |
| 454 | struct timespec ts_sent; | ||
| 436 | struct timespec start; | 455 | struct timespec start; |
| 437 | struct timespec now; | 456 | struct timespec now; |
| 438 | 457 | ||
| @@ -454,90 +473,99 @@ my_loop( | |||
| 454 | stats_avg = 0; | 473 | stats_avg = 0; |
| 455 | stats_avg_adj = 0; | 474 | stats_avg_adj = 0; |
| 456 | 475 | ||
| 457 | // start clock | 476 | // initialize timers |
| 458 | clock_gettime(CLOCK_MONOTONIC_RAW, &start); | 477 | clock_gettime(CLOCK_MONOTONIC_RAW, &start); |
| 459 | start.tv_sec -= cnf_interval; | 478 | start.tv_sec -= cnf_interval; |
| 460 | epoch = 0; | 479 | ts_sent.tv_sec = start.tv_sec; |
| 480 | ts_sent.tv_nsec = start.tv_nsec; | ||
| 461 | 481 | ||
| 462 | // master loop | 482 | // master loop |
| 463 | while (!(should_stop)) | 483 | while (!(should_stop)) |
| 464 | { | 484 | { |
| 465 | // calculate loop epoch | 485 | // calculate loop epoch |
| 466 | clock_gettime(CLOCK_MONOTONIC_RAW, &now); | 486 | clock_gettime(CLOCK_MONOTONIC_RAW, &now); |
| 467 | epoch = ((uint64_t)now.tv_sec * 10000) + ((uint64_t)now.tv_nsec / 100000); | 487 | epoch_usec = my_sec2usec((uint64_t)now.tv_sec) + my_nsec2usec((uint64_t)now.tv_nsec); |
| 468 | epoch -= ((uint64_t)start.tv_sec * 10000) + ((uint64_t)start.tv_nsec / 100000); | 488 | epoch_usec -= my_sec2usec((uint64_t)start.tv_sec) + my_nsec2usec((uint64_t)start.tv_nsec); |
| 469 | 489 | ||
| 470 | // trigger stop | 490 | // trigger stop |
| 471 | if ( ((cnf_count)) && (stats_sent >= cnf_count) ) | 491 | if ( ((cnf_count)) && (stats_sent >= cnf_count) ) |
| 472 | { | 492 | { |
| 473 | epoch_max = cnf_count * (uint64_t)cnf_interval * 10000; | 493 | if (stats_rcvd == stats_sent) |
| 474 | epoch_max += (uint64_t)cnf_timeout * 10000; | 494 | { |
| 475 | if (( epoch >= epoch_max) || (stats_rcvd >= stats_sent)) | ||
| 476 | should_stop = 1; | 495 | should_stop = 1; |
| 496 | continue; | ||
| 497 | }; | ||
| 498 | if (my_timespec_delta(&now, &ts_sent, NULL) > my_sec2usec((uint64_t)cnf_timeout)) | ||
| 499 | { | ||
| 500 | should_stop = 1; | ||
| 501 | continue; | ||
| 502 | }; | ||
| 477 | }; | 503 | }; |
| 478 | 504 | ||
| 479 | // send UDP echo request | 505 | // send UDP echo request |
| 480 | if ((stats_sent < (epoch/(10000*cnf_interval))) && ((stats_sent < cnf_count) || (!(cnf_count))) ) | 506 | if ((stats_sent < (epoch_usec/my_sec2usec(cnf_interval))) && ((stats_sent < cnf_count) || (!(cnf_count))) ) |
| 481 | { | 507 | { |
| 482 | stats_sent++; | 508 | stats_sent++; |
| 483 | sndbuff->req_sn = htonl((uint32_t)stats_sent); | 509 | sndbuff->req_sn = htonl((uint32_t)stats_sent); |
| 510 | sndbuff->send_time.tv_sec = now.tv_sec; | ||
| 511 | sndbuff->send_time.tv_nsec = now.tv_nsec; | ||
| 512 | ts_sent.tv_sec = now.tv_sec; | ||
| 513 | ts_sent.tv_nsec = now.tv_nsec; | ||
| 484 | send(s, sndbuff, cnf_packetsize, 0); | 514 | send(s, sndbuff, cnf_packetsize, 0); |
| 485 | }; | 515 | }; |
| 486 | 516 | ||
| 487 | // receive UDP echo response | 517 | // receive UDP echo response |
| 488 | if ((rc = poll(fds, 1, 0)) > 0) | 518 | if ((rc = poll(fds, 1, 0)) <= 0) |
| 489 | { | 519 | { |
| 490 | if ((size = recv(s, rcvbuff, cnf_packetsize, 0)) == (ssize_t)cnf_packetsize) | 520 | usleep(50); |
| 491 | { | 521 | continue; |
| 492 | rcvbuff->req_sn = ntohl(rcvbuff->req_sn); | 522 | }; |
| 493 | rcvbuff->res_sn = ntohl(rcvbuff->res_sn); | 523 | |
| 494 | rcvbuff->recv_time = ntohl(rcvbuff->recv_time); | 524 | // reads packet |
| 495 | rcvbuff->reply_time = ntohl(rcvbuff->reply_time); | 525 | if ((size = recv(s, rcvbuff, cnf_packetsize, 0)) != (ssize_t)cnf_packetsize) |
| 496 | rcvbuff->failures = ntohl(rcvbuff->failures); | 526 | continue; |
| 497 | rcvbuff->iteration = ntohl(1); | 527 | rcvbuff->req_sn = ntohl(rcvbuff->req_sn); |
| 498 | if ((cnf_debug)) | 528 | rcvbuff->res_sn = ntohl(rcvbuff->res_sn); |
| 499 | { | 529 | rcvbuff->recv_time = ntohl(rcvbuff->recv_time); |
| 500 | printf(" packet: GenSN/REspSN: %08" PRIx32 " %08" PRIx32 "\n", rcvbuff->req_sn, rcvbuff->res_sn); | 530 | rcvbuff->reply_time = ntohl(rcvbuff->reply_time); |
| 501 | printf(" Recv/Reply Time: %08" PRIx32 " %08" PRIx32 "\n", rcvbuff->recv_time, rcvbuff->reply_time); | 531 | rcvbuff->failures = ntohl(rcvbuff->failures); |
| 502 | printf(" Failures: %08" PRIx32 "\n", rcvbuff->failures); | 532 | rcvbuff->iteration = ntohl(1); |
| 503 | printf(" Iteration: %08" PRIx32 "\n", rcvbuff->iteration); | 533 | if ((cnf_debug)) |
| 504 | }; | 534 | { |
| 505 | stats_rcvd++; | 535 | printf(" packet: GenSN/REspSN: %08" PRIx32 " %08" PRIx32 "\n", rcvbuff->req_sn, rcvbuff->res_sn); |
| 506 | delay = rcvbuff->reply_time - rcvbuff->recv_time; | 536 | printf(" Recv/Reply Time: %08" PRIx32 " %08" PRIx32 "\n", rcvbuff->recv_time, rcvbuff->reply_time); |
| 507 | delay /= 100000000; | 537 | printf(" Failures: %08" PRIx32 "\n", rcvbuff->failures); |
| 508 | epoch -= (rcvbuff->req_sn * 10000); | 538 | printf(" Iteration: %08" PRIx32 "\n", rcvbuff->iteration); |
| 509 | epoch_adj = epoch - delay; | 539 | }; |
| 510 | stats_avg += epoch; | 540 | stats_rcvd++; |
| 511 | stats_avg_adj += epoch_adj; | 541 | |
| 512 | if ( (!(stats_min)) || (epoch < stats_min) ) | 542 | // performs stats on packet |
| 513 | stats_min = epoch; | 543 | pckt_time = my_timespec_delta(&now, &rcvbuff->send_time, NULL); |
| 514 | if ( (!(stats_max)) || (epoch > stats_max) ) | 544 | pckt_delay = rcvbuff->reply_time - rcvbuff->recv_time; |
| 515 | stats_max = epoch; | 545 | pckt_time_adj = pckt_time - pckt_delay; |
| 516 | if ( (!(stats_min_adj)) || (epoch_adj < stats_min_adj) ) | 546 | stats_avg += pckt_time; |
| 517 | stats_min_adj = epoch_adj; | 547 | stats_avg_adj += pckt_time_adj; |
| 518 | if ( (!(stats_max_adj)) || (epoch_adj > stats_max_adj) ) | 548 | stats_min = ( (!(stats_min)) || (pckt_time < stats_min) ) ? pckt_time : stats_min; |
| 519 | stats_max_adj = epoch_adj; | 549 | stats_max = ( (!(stats_max)) || (pckt_time > stats_max) ) ? pckt_time : stats_max; |
| 520 | if ((cnf_echoplus)) | 550 | stats_min_adj = ( (!(stats_min_adj)) || (pckt_time_adj < stats_min_adj) ) ? pckt_time_adj : stats_min_adj; |
| 521 | { | 551 | stats_max_adj = ( (!(stats_max_adj)) || (pckt_time_adj > stats_max_adj) ) ? pckt_time_adj : stats_max_adj; |
| 522 | printf("udpecho_seq=%u failures=%" PRIu32 " time=%" PRIu64 ".%" PRIu64 " ms delay=%" PRIu64 ".%" PRIu64 " ms adj_time=%" PRIu64 ".%" PRIu64 " ms\n", | 552 | |
| 523 | rcvbuff->req_sn, | 553 | // print packet |
| 524 | rcvbuff->failures, | 554 | if (!(cnf_echoplus)) |
| 525 | epoch/10, epoch%10, | ||
| 526 | delay/10, delay%10, | ||
| 527 | epoch_adj/10, epoch_adj%10 | ||
| 528 | ); | ||
| 529 | } else | ||
| 530 | { | ||
| 531 | printf("udpecho_seq=%u time=%" PRIu64 ".%" PRIu64 " ms\n", | ||
| 532 | rcvbuff->req_sn, | ||
| 533 | epoch/10, epoch%10 | ||
| 534 | ); | ||
| 535 | }; | ||
| 536 | }; | ||
| 537 | } else | ||
| 538 | { | 555 | { |
| 539 | usleep(100); | 556 | printf("udpecho_seq=%u time=%" PRIu64 ".%" PRIu64 " ms\n", |
| 557 | rcvbuff->req_sn, | ||
| 558 | my_usec2msec(pckt_time), ((pckt_time%1000)/100) | ||
| 559 | ); | ||
| 560 | continue; | ||
| 540 | }; | 561 | }; |
| 562 | printf("udpecho_seq=%u failures=%" PRIu32 " time=%" PRIu64 ".%" PRIu64 " ms delay=%" PRIu64 ".%" PRIu64 " ms adj_time=%" PRIu64 ".%" PRIu64 " ms\n", | ||
| 563 | rcvbuff->req_sn, | ||
| 564 | rcvbuff->failures, | ||
| 565 | my_usec2msec(pckt_time), my_usec2msec_tenths(pckt_time), | ||
| 566 | my_usec2msec(pckt_delay), my_usec2msec_tenths(pckt_delay), | ||
| 567 | my_usec2msec(pckt_time_adj), my_usec2msec_tenths(pckt_time_adj) | ||
| 568 | ); | ||
| 541 | }; | 569 | }; |
| 542 | 570 | ||
| 543 | if (!(cnf_silent)) | 571 | if (!(cnf_silent)) |
| @@ -549,19 +577,19 @@ my_loop( | |||
| 549 | stats_rcvd, | 577 | stats_rcvd, |
| 550 | ((stats_sent - stats_rcvd) * 100) / stats_sent, | 578 | ((stats_sent - stats_rcvd) * 100) / stats_sent, |
| 551 | (((stats_sent - stats_rcvd) * 1000) / stats_sent) % 10 | 579 | (((stats_sent - stats_rcvd) * 1000) / stats_sent) % 10 |
| 552 | ); | 580 | ); |
| 553 | printf("round-trip min/avg/max = %" PRIu64 ".%" PRIu64 "/%" PRIu64 ".%" PRIu64 "/%" PRIu64 ".%" PRIu64 " ms\n", | 581 | printf("round-trip min/avg/max = %" PRIu64 ".%" PRIu64 "/%" PRIu64 ".%" PRIu64 "/%" PRIu64 ".%" PRIu64 " ms\n", |
| 554 | stats_min/10, stats_min%10, | 582 | my_usec2msec(stats_min), my_usec2msec_tenths(stats_min), |
| 555 | (stats_avg/stats_rcvd)/10, (stats_avg/stats_rcvd)%10, | 583 | my_usec2msec(stats_avg/stats_rcvd), my_usec2msec_tenths(stats_avg/stats_rcvd), |
| 556 | stats_max/10, stats_max%10 | 584 | my_usec2msec(stats_max), my_usec2msec_tenths(stats_max) |
| 557 | ); | 585 | ); |
| 558 | if ((cnf_echoplus)) | 586 | if ((cnf_echoplus)) |
| 559 | { | 587 | { |
| 560 | printf("adjusted round-trip min/avg/max = %" PRIu64 ".%" PRIu64 "/%" PRIu64 ".%" PRIu64 "/%" PRIu64 ".%" PRIu64 " ms\n", | 588 | printf("adjusted round-trip min/avg/max = %" PRIu64 ".%" PRIu64 "/%" PRIu64 ".%" PRIu64 "/%" PRIu64 ".%" PRIu64 " ms\n", |
| 561 | stats_min_adj/10, stats_min_adj%10, | 589 | my_usec2msec(stats_min_adj), my_usec2msec_tenths(stats_min_adj), |
| 562 | (stats_avg_adj/stats_rcvd)/10, (stats_avg_adj/stats_rcvd)%10, | 590 | my_usec2msec(stats_avg_adj/stats_rcvd), my_usec2msec_tenths(stats_avg_adj/stats_rcvd), |
| 563 | stats_max_adj/10, stats_max_adj%10 | 591 | my_usec2msec(stats_max_adj), my_usec2msec_tenths(stats_max_adj) |
| 564 | ); | 592 | ); |
| 565 | }; | 593 | }; |
| 566 | }; | 594 | }; |
| 567 | 595 | ||
| @@ -651,6 +679,39 @@ my_stop( | |||
| 651 | } | 679 | } |
| 652 | 680 | ||
| 653 | 681 | ||
| 682 | // calculates delta between timespecs and returns result as microscond | ||
| 683 | uint64_t | ||
| 684 | my_timespec_delta( | ||
| 685 | struct timespec * ts1, | ||
| 686 | struct timespec * ts2, | ||
| 687 | struct timespec * delta ) | ||
| 688 | { | ||
| 689 | struct timespec ts; | ||
| 690 | uint64_t usec; | ||
| 691 | |||
| 692 | assert(ts1 != NULL); | ||
| 693 | assert(ts2 != NULL); | ||
| 694 | |||
| 695 | if (!(delta)) | ||
| 696 | delta = &ts; | ||
| 697 | |||
| 698 | delta->tv_sec = ts1->tv_sec; | ||
| 699 | delta->tv_nsec = ts1->tv_nsec; | ||
| 700 | if (delta->tv_nsec < ts2->tv_nsec) | ||
| 701 | { | ||
| 702 | delta->tv_sec--; | ||
| 703 | delta->tv_nsec += my_sec2nsec(1); | ||
| 704 | }; | ||
| 705 | delta->tv_sec -= ts2->tv_sec; | ||
| 706 | delta->tv_nsec -= ts2->tv_nsec; | ||
| 707 | |||
| 708 | usec = my_sec2usec(delta->tv_sec); | ||
| 709 | usec += my_nsec2usec(delta->tv_nsec); | ||
| 710 | |||
| 711 | return(usec); | ||
| 712 | } | ||
| 713 | |||
| 714 | |||
| 654 | // display program usage | 715 | // display program usage |
| 655 | void | 716 | void |
| 656 | my_usage( | 717 | my_usage( |
