From 056361fc5d2b849795bf247b7f3ad8b8a0726170 Mon Sep 17 00:00:00 2001 From: Jef Poskanzer Date: Tue, 26 Nov 2013 14:47:15 -0800 Subject: [PATCH] Show user/system CPU usage as well as total. --- src/iperf.h | 4 ++-- src/iperf_api.c | 22 +++++++++++++++------- src/iperf_client_api.c | 2 +- src/iperf_server_api.c | 2 +- src/iperf_util.c | 19 ++++++++++++++++--- src/iperf_util.h | 2 +- src/locale.c | 2 +- 7 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/iperf.h b/src/iperf.h index b8ec5ca..5515836 100644 --- a/src/iperf.h +++ b/src/iperf.h @@ -179,8 +179,8 @@ struct iperf_test Timer *stats_timer; Timer *reporter_timer; - double cpu_util; /* cpu utilization of the test */ - double remote_cpu_util; /* cpu utilization for the remote host/client */ + double cpu_util[3]; /* cpu utilization of the test - total, user, system */ + double remote_cpu_util[3]; /* cpu utilization for the remote host/client - total, user, system */ int num_streams; /* total streams in the test (-P) */ diff --git a/src/iperf_api.c b/src/iperf_api.c index e92fc9e..2aee4e7 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -1102,7 +1102,9 @@ send_results(struct iperf_test *test) i_errno = IEPACKAGERESULTS; r = -1; } else { - cJSON_AddFloatToObject(j, "cpu_util", test->cpu_util); + cJSON_AddFloatToObject(j, "cpu_util_total", test->cpu_util[0]); + cJSON_AddFloatToObject(j, "cpu_util_user", test->cpu_util[1]); + cJSON_AddFloatToObject(j, "cpu_util_system", test->cpu_util[2]); if ( ! test->sender ) sender_has_retransmits = -1; else @@ -1148,7 +1150,9 @@ get_results(struct iperf_test *test) { int r = 0; cJSON *j; - cJSON *j_cpu_util; + cJSON *j_cpu_util_total; + cJSON *j_cpu_util_user; + cJSON *j_cpu_util_system; cJSON *j_sender_has_retransmits; int result_has_retransmits; cJSON *j_streams; @@ -1171,13 +1175,17 @@ get_results(struct iperf_test *test) i_errno = IERECVRESULTS; r = -1; } else { - j_cpu_util = cJSON_GetObjectItem(j, "cpu_util"); + j_cpu_util_total = cJSON_GetObjectItem(j, "cpu_util_total"); + j_cpu_util_user = cJSON_GetObjectItem(j, "cpu_util_user"); + j_cpu_util_system = cJSON_GetObjectItem(j, "cpu_util_system"); j_sender_has_retransmits = cJSON_GetObjectItem(j, "sender_has_retransmits"); - if (j_cpu_util == NULL || j_sender_has_retransmits == NULL) { + if (j_cpu_util_total == NULL || j_cpu_util_user == NULL || j_cpu_util_system == NULL || j_sender_has_retransmits == NULL) { i_errno = IERECVRESULTS; r = -1; } else { - test->remote_cpu_util = j_cpu_util->valuefloat; + test->remote_cpu_util[0] = j_cpu_util_total->valuefloat; + test->remote_cpu_util[1] = j_cpu_util_user->valuefloat; + test->remote_cpu_util[2] = j_cpu_util_system->valuefloat; result_has_retransmits = j_sender_has_retransmits->valueint; if (! test->sender) test->sender_has_retransmits = result_has_retransmits; @@ -1833,9 +1841,9 @@ iperf_print_results(struct iperf_test *test) } if (test->json_output) - cJSON_AddItemToObject(test->json_end, "cpu_utilization_percent", iperf_json_printf("host: %f remote: %f", (double) test->cpu_util, (double) test->remote_cpu_util)); + cJSON_AddItemToObject(test->json_end, "cpu_utilization_percent", iperf_json_printf("host_total: %f host_user: %f host_system: %f remote_total: %f remote_user: %f remote_system: %f", (double) test->cpu_util[0], (double) test->cpu_util[1], (double) test->cpu_util[2], (double) test->remote_cpu_util[0], (double) test->remote_cpu_util[1], (double) test->remote_cpu_util[2])); else if (test->verbose) - iprintf(test, report_cpu, report_local, test->sender?report_sender:report_receiver, test->cpu_util, report_remote, test->sender?report_receiver:report_sender, test->remote_cpu_util); + iprintf(test, report_cpu, report_local, test->sender?report_sender:report_receiver, test->cpu_util[0], test->cpu_util[1], test->cpu_util[2], report_remote, test->sender?report_receiver:report_sender, test->remote_cpu_util[0], test->remote_cpu_util[1], test->remote_cpu_util[2]); } /**************************************************************************/ diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c index 7c375fb..97b5eb0 100644 --- a/src/iperf_client_api.c +++ b/src/iperf_client_api.c @@ -438,7 +438,7 @@ iperf_run_client(struct iperf_test * test) continue; /* not done */ } /* Yes, done! Send TEST_END. */ - cpu_util(&test->cpu_util); + cpu_util(test->cpu_util); test->stats_callback(test); if (iperf_set_send_state(test, TEST_END) != 0) return -1; diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c index 6ded209..385421b 100644 --- a/src/iperf_server_api.c +++ b/src/iperf_server_api.c @@ -181,7 +181,7 @@ iperf_handle_message_server(struct iperf_test *test) case TEST_START: break; case TEST_END: - cpu_util(&test->cpu_util); + cpu_util(test->cpu_util); test->stats_callback(test); SLIST_FOREACH(sp, &test->streams, streams) { FD_CLR(sp->socket, &test->read_set); diff --git a/src/iperf_util.c b/src/iperf_util.c index 1b25dd6..4ac55e9 100644 --- a/src/iperf_util.c +++ b/src/iperf_util.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -157,27 +158,39 @@ delay(int us) void -cpu_util(double *pcpu) +cpu_util(double pcpu[3]) { static struct timeval last; static clock_t clast; + static struct rusage rlast; struct timeval temp; clock_t ctemp; + struct rusage rtemp; double timediff; + double userdiff; + double systemdiff; if (pcpu == NULL) { gettimeofday(&last, NULL); clast = clock(); + getrusage(RUSAGE_SELF, &rlast); return; } gettimeofday(&temp, NULL); ctemp = clock(); + getrusage(RUSAGE_SELF, &rtemp); timediff = ((temp.tv_sec * 1000000.0 + temp.tv_usec) - - (last.tv_sec * 1000000.0 + last.tv_usec)); + (last.tv_sec * 1000000.0 + last.tv_usec)); + userdiff = ((rtemp.ru_utime.tv_sec * 1000000.0 + rtemp.ru_utime.tv_usec) - + (rlast.ru_utime.tv_sec * 1000000.0 + rlast.ru_utime.tv_usec)); + systemdiff = ((rtemp.ru_stime.tv_sec * 1000000.0 + rtemp.ru_stime.tv_usec) - + (rlast.ru_stime.tv_sec * 1000000.0 + rlast.ru_stime.tv_usec)); - *pcpu = ((ctemp - clast) / timediff) * 100; + pcpu[0] = ((ctemp - clast) / timediff) * 100; + pcpu[1] = (userdiff / timediff) * 100; + pcpu[2] = (systemdiff / timediff) * 100; } char* diff --git a/src/iperf_util.h b/src/iperf_util.h index 1ac9c26..cc389cc 100644 --- a/src/iperf_util.h +++ b/src/iperf_util.h @@ -24,7 +24,7 @@ double timeval_diff(struct timeval *tv0, struct timeval *tv1); int delay(int64_t ns); -void cpu_util(double *); +void cpu_util(double pcpu[3]); char* get_system_info(void); diff --git a/src/locale.c b/src/locale.c index 26ede80..b3a5cc3 100644 --- a/src/locale.c +++ b/src/locale.c @@ -279,7 +279,7 @@ const char reportCSV_peer[] = "%s,%u,%s,%u"; const char report_cpu[] = -"CPU Utilization: %s/%s %.1f%%, %s/%s %.1f%%\n"; +"CPU Utilization: %s/%s %.1f%% (%.1f%%u/%.1f%%s), %s/%s %.1f%% (%.1f%%u/%.1f%%s)\n"; const char report_local[] = "local"; const char report_remote[] = "remote";