Re-do of how --omit works.

This commit is contained in:
Jef Poskanzer 2013-10-24 14:08:04 -07:00
parent ea5d93b241
commit a953f5aa2c
6 changed files with 115 additions and 80 deletions

View File

@ -27,6 +27,7 @@ struct iperf_interval_results
struct timeval interval_start_time;
struct timeval interval_end_time;
float interval_duration;
int omitted;
#if defined(linux) || defined(__FreeBSD__)
struct tcp_info tcpInfo; /* getsockopt(TCP_INFO) for Linux and FreeBSD */
int this_retrans;

View File

@ -938,8 +938,8 @@ iperf_sum_results(struct iperf_test *test)
{
struct iperf_stream *sp;
SLIST_FOREACH(sp, &test->streams, streams) {
if (test->sender && test->sender_has_retransmits) {
if (test->sender && test->sender_has_retransmits) {
SLIST_FOREACH(sp, &test->streams, streams) {
sp->result->retransmits = get_tcpinfo_total_retransmits(TAILQ_LAST(&sp->result->interval_results, irlisthead));
}
}
@ -1563,6 +1563,7 @@ iperf_stats_callback(struct iperf_test *test)
struct iperf_interval_results *irp, temp;
int prev_total_retransmits;
temp.omitted = test->omitting;
SLIST_FOREACH(sp, &test->streams, streams) {
rp = sp->result;
@ -1652,14 +1653,14 @@ iperf_print_intermediate(struct iperf_test *test)
end_time = timeval_diff(&sp->result->start_time,&irp->interval_end_time);
if (test->sender && test->sender_has_retransmits) {
if (test->json_output)
cJSON_AddItemToObject(json_interval, "sum", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d", (double) start_time, (double) end_time, (double) irp->interval_duration, (int64_t) bytes, bandwidth * 8, (int64_t) retransmits));
cJSON_AddItemToObject(json_interval, "sum", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d omitted: %b", (double) start_time, (double) end_time, (double) irp->interval_duration, (int64_t) bytes, bandwidth * 8, (int64_t) retransmits, irp->omitted));
else
printf(report_sum_bw_retrans_format, start_time, end_time, ubuf, nbuf, retransmits);
printf(report_sum_bw_retrans_format, start_time, end_time, ubuf, nbuf, retransmits, irp->omitted?report_omitted:"");
} else {
if (test->json_output)
cJSON_AddItemToObject(json_interval, "sum", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f", (double) start_time, (double) end_time, (double) irp->interval_duration, (int64_t) bytes, bandwidth * 8));
cJSON_AddItemToObject(json_interval, "sum", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f omitted: %b", (double) start_time, (double) end_time, (double) irp->interval_duration, (int64_t) bytes, bandwidth * 8, test->omitting));
else
printf(report_sum_bw_format, start_time, end_time, ubuf, nbuf);
printf(report_sum_bw_format, start_time, end_time, ubuf, nbuf, test->omitting?report_omitted:"");
}
}
}
@ -1737,12 +1738,12 @@ iperf_print_results(struct iperf_test *test)
if (test->json_output)
cJSON_AddItemToObject(json_summary_stream, "sent", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_sent, bandwidth * 8, (int64_t) sp->result->retransmits));
else
printf(report_bw_retrans_format, sp->socket, start_time, end_time, ubuf, nbuf, sp->result->retransmits);
printf(report_bw_retrans_format, sp->socket, start_time, end_time, ubuf, nbuf, sp->result->retransmits, "");
} else {
if (test->json_output)
cJSON_AddItemToObject(json_summary_stream, "sent", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_sent, bandwidth * 8));
else
printf(report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf);
printf(report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf, "");
}
} else {
out_of_order_percent = 100.0 * sp->cnt_error / (sp->packet_count - sp->omitted_packet_count);
@ -1777,7 +1778,7 @@ iperf_print_results(struct iperf_test *test)
if (test->json_output)
cJSON_AddItemToObject(json_summary_stream, "received", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_received, bandwidth * 8));
else
printf(report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf);
printf(report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf, "");
}
}
@ -1792,12 +1793,12 @@ iperf_print_results(struct iperf_test *test)
if (test->json_output)
cJSON_AddItemToObject(test->json_end, "sum_sent", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d", (double) start_time, (double) end_time, (double) end_time, (int64_t) total_sent, bandwidth * 8, (int64_t) total_retransmits));
else
printf(report_sum_bw_retrans_format, start_time, end_time, ubuf, nbuf, total_retransmits);
printf(report_sum_bw_retrans_format, start_time, end_time, ubuf, nbuf, total_retransmits, "");
} else {
if (test->json_output)
cJSON_AddItemToObject(test->json_end, "sum_sent", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f", (double) start_time, (double) end_time, (double) end_time, (int64_t) total_sent, bandwidth * 8));
else
printf(report_sum_bw_format, start_time, end_time, ubuf, nbuf);
printf(report_sum_bw_format, start_time, end_time, ubuf, nbuf, "");
}
unit_snprintf(ubuf, UNIT_LEN, (double) total_received, 'A');
bandwidth = (double) total_received / (double) end_time;
@ -1807,7 +1808,7 @@ iperf_print_results(struct iperf_test *test)
if (test->json_output)
cJSON_AddItemToObject(test->json_end, "sum_received", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f", (double) start_time, (double) end_time, (double) end_time, (int64_t) total_received, bandwidth * 8));
else
printf(report_sum_bw_format, start_time, end_time, ubuf, nbuf);
printf(report_sum_bw_format, start_time, end_time, ubuf, nbuf, "");
} else {
avg_jitter /= test->num_streams;
loss_percent = 100.0 * lost_packets / total_packets;
@ -1891,14 +1892,14 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
if (test->sender && test->sender_has_retransmits) {
if (test->json_output)
cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->this_retrans));
cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->this_retrans, irp->omitted));
else
printf(report_bw_retrans_format, sp->socket, st, et, ubuf, nbuf, irp->this_retrans);
printf(report_bw_retrans_format, sp->socket, st, et, ubuf, nbuf, irp->this_retrans, irp->omitted?report_omitted:"");
} else {
if (test->json_output)
cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8));
cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, irp->omitted));
else
printf(report_bw_format, sp->socket, st, et, ubuf, nbuf);
printf(report_bw_format, sp->socket, st, et, ubuf, nbuf, irp->omitted?report_omitted:"");
}
}

View File

@ -83,48 +83,8 @@ reporter_timer_proc(TimerClientData client_data, struct timeval *nowP)
test->reporter_callback(test);
}
static void
client_omit_timer_proc(TimerClientData client_data, struct timeval *nowP)
{
struct iperf_test *test = client_data.p;
TimerClientData cd;
test->omit_timer = NULL;
test->omitting = 0;
iperf_reset_stats(test);
if (test->verbose && !test->json_output)
printf("Finished omit period, starting real test\n");
/* Create timers. */
if (test->settings->bytes == 0) {
test->done = 0;
cd.p = test;
test->timer = tmr_create(nowP, test_timer_proc, cd, test->duration * SEC_TO_US, 0);
if (test->timer == NULL) {
i_errno = IEINITTEST;
return;
}
}
if (test->stats_interval != 0) {
cd.p = test;
test->stats_timer = tmr_create(nowP, stats_timer_proc, cd, test->stats_interval * SEC_TO_US, 1);
if (test->stats_timer == NULL) {
i_errno = IEINITTEST;
return;
}
}
if (test->reporter_interval != 0) {
cd.p = test;
test->reporter_timer = tmr_create(nowP, reporter_timer_proc, cd, test->reporter_interval * SEC_TO_US, 1);
if (test->reporter_timer == NULL) {
i_errno = IEINITTEST;
return;
}
}
}
static int
create_client_omit_timer(struct iperf_test * test)
create_client_timers(struct iperf_test * test)
{
struct timeval now;
TimerClientData cd;
@ -133,12 +93,72 @@ create_client_omit_timer(struct iperf_test * test)
i_errno = IEINITTEST;
return -1;
}
test->omitting = 1;
cd.p = test;
test->omit_timer = tmr_create(&now, client_omit_timer_proc, cd, test->omit * SEC_TO_US, 0);
if (test->omit_timer == NULL) {
i_errno = IEINITTEST;
return -1;
test->timer = test->stats_timer = test->reporter_timer = NULL;
if (test->settings->bytes == 0) {
test->done = 0;
test->timer = tmr_create(&now, test_timer_proc, cd, ( test->duration + test->omit ) * SEC_TO_US, 0);
if (test->timer == NULL) {
i_errno = IEINITTEST;
return -1;
}
}
if (test->stats_interval != 0) {
test->stats_timer = tmr_create(&now, stats_timer_proc, cd, test->stats_interval * SEC_TO_US, 1);
if (test->stats_timer == NULL) {
i_errno = IEINITTEST;
return -1;
}
}
if (test->reporter_interval != 0) {
test->reporter_timer = tmr_create(&now, reporter_timer_proc, cd, test->reporter_interval * SEC_TO_US, 1);
if (test->reporter_timer == NULL) {
i_errno = IEINITTEST;
return -1;
}
}
return 0;
}
static void
client_omit_timer_proc(TimerClientData client_data, struct timeval *nowP)
{
struct iperf_test *test = client_data.p;
test->omit_timer = NULL;
test->omitting = 0;
iperf_reset_stats(test);
if (test->verbose && !test->json_output && test->reporter_interval == 0)
printf("Finished omit period, starting real test\n");
/* Reset the timers. */
if (test->stats_timer != NULL)
tmr_reset(nowP, test->stats_timer);
if (test->reporter_timer != NULL)
tmr_reset(nowP, test->reporter_timer);
}
static int
create_client_omit_timer(struct iperf_test * test)
{
struct timeval now;
TimerClientData cd;
if (test->omit == 0) {
test->omit_timer = NULL;
test->omitting = 0;
} else {
if (gettimeofday(&now, NULL) < 0) {
i_errno = IEINITTEST;
return -1;
}
test->omitting = 1;
cd.p = test;
test->omit_timer = tmr_create(&now, client_omit_timer_proc, cd, test->omit * SEC_TO_US, 0);
if (test->omit_timer == NULL) {
i_errno = IEINITTEST;
return -1;
}
}
return 0;
}
@ -172,6 +192,8 @@ iperf_handle_message_client(struct iperf_test *test)
case TEST_START:
if (iperf_init_test(test) < 0)
return -1;
if (create_client_timers(test) < 0)
return -1;
if (create_client_omit_timer(test) < 0)
return -1;
if (!test->reverse)
@ -337,16 +359,18 @@ iperf_run_client(struct iperf_test * test)
if (test->state == TEST_RUNNING) {
/* Is this our first time really running? */
if (startup && ! test->omitting) {
if (startup) {
startup = 0;
/* Can we switch to SIGALRM mode? There are a bunch of
** cases where either it won't work or it's ill-advised.
/* Decide which concurrency model to use for the real test.
** SIGALRM is less overhead but there are a bunch of cases
** where it either won't work or is ill-advised.
*/
if (test->may_use_sigalrm && test->settings->rate == 0 &&
(test->stats_interval == 0 || test->stats_interval > 1) &&
test->stats_interval == (int) test->stats_interval &&
(test->reporter_interval == 0 || test->reporter_interval > 1) &&
test->reporter_interval == (int) test->reporter_interval &&
(test->omit == 0 || test->omit > 1) &&
! test->reverse) {
concurrency_model = CM_SIGALRM;
test->multisend = 1;

View File

@ -289,7 +289,7 @@ server_omit_timer_proc(TimerClientData client_data, struct timeval *nowP)
test->omit_timer = NULL;
test->omitting = 0;
iperf_reset_stats(test);
if (test->verbose && !test->json_output)
if (test->verbose && !test->json_output && test->reporter_interval == 0)
printf("Finished omit period, starting real test\n");
}
@ -299,17 +299,23 @@ create_server_omit_timer(struct iperf_test * test)
struct timeval now;
TimerClientData cd;
if (gettimeofday(&now, NULL) < 0) {
i_errno = IEINITTEST;
return -1;
}
test->omitting = 1;
cd.p = test;
test->omit_timer = tmr_create(&now, server_omit_timer_proc, cd, test->omit * SEC_TO_US, 0);
if (test->omit_timer == NULL) {
i_errno = IEINITTEST;
return -1;
if (test->omit == 0) {
test->omit_timer = NULL;
test->omitting = 0;
} else {
if (gettimeofday(&now, NULL) < 0) {
i_errno = IEINITTEST;
return -1;
}
test->omitting = 1;
cd.p = test;
test->omit_timer = tmr_create(&now, server_omit_timer_proc, cd, test->omit * SEC_TO_US, 0);
if (test->omit_timer == NULL) {
i_errno = IEINITTEST;
return -1;
}
}
return 0;
}

View File

@ -191,23 +191,25 @@ const char report_bw_udp_header[] =
Datagrams\n";
const char report_bw_format[] =
"[%3d] %6.2f-%-6.2f sec %ss %ss/sec\n";
"[%3d] %6.2f-%-6.2f sec %ss %ss/sec%s\n";
const char report_bw_retrans_format[] =
"[%3d] %6.2f-%-6.2f sec %ss %ss/sec %d\n";
"[%3d] %6.2f-%-6.2f sec %ss %ss/sec %d%s\n";
const char report_bw_udp_format[] =
"[%3d] %6.2f-%-6.2f sec %ss %ss/sec %5.3f ms %d/%d (%.2g%%)\n";
const char report_sum_bw_format[] =
"[SUM] %6.2f-%-6.2f sec %ss %ss/sec\n";
"[SUM] %6.2f-%-6.2f sec %ss %ss/sec%s\n";
const char report_sum_bw_retrans_format[] =
"[SUM] %6.2f-%-6.2f sec %ss %ss/sec %d\n";
"[SUM] %6.2f-%-6.2f sec %ss %ss/sec %d%s\n";
const char report_sum_bw_udp_format[] =
"[SUM] %6.2f-%-6.2f sec %ss %ss/sec %5.3f ms %d/%d (%.2g%%)\n";
const char report_omitted[] = " (omitted)";
const char report_bw_separator[] =
"- - - - - - - - - - - - - - - - - - - - - - - - -\n";

View File

@ -41,6 +41,7 @@ extern const char report_bw_udp_format[] ;
extern const char report_sum_bw_format[] ;
extern const char report_sum_bw_retrans_format[] ;
extern const char report_sum_bw_udp_format[] ;
extern const char report_omitted[] ;
extern const char report_bw_separator[] ;
extern const char report_outoforder[] ;
extern const char report_sum_outoforder[] ;