aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Fox-Moore <ben.foxmoore@accelleran.com>2018-05-16 23:49:45 +0200
committerBen Fox-Moore <ben.foxmoore@accelleran.com>2018-05-17 14:09:52 +0200
commitcde81d76400a5eaed1e7986fc5df62b420122aeb (patch)
tree60c1822f1908b2d57dffbbebe669aa9d600dffe7
parent829d619ab435e7975ae1e8cbaf93117d98e4462c (diff)
downloadiperf3-cde81d76400a5eaed1e7986fc5df62b420122aeb.tar.gz
Add initial portable time abstraction
-rwxr-xr-xconfigure69
-rw-r--r--configure.ac4
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Makefile.in38
-rwxr-xr-xsrc/iperf.h11
-rwxr-xr-xsrc/iperf_api.c80
-rwxr-xr-xsrc/iperf_api.h3
-rw-r--r--src/iperf_client_api.c23
-rw-r--r--src/iperf_config.h.in3
-rw-r--r--src/iperf_server_api.c23
-rw-r--r--src/iperf_time.c156
-rw-r--r--src/iperf_time.h49
-rw-r--r--src/iperf_udp.c27
-rw-r--r--src/iperf_util.c13
-rw-r--r--src/t_timer.c9
-rw-r--r--src/timer.c68
-rw-r--r--src/timer.h17
17 files changed, 455 insertions, 140 deletions
diff --git a/configure b/configure
index 1250a42..5914466 100755
--- a/configure
+++ b/configure
@@ -13090,6 +13090,75 @@ $as_echo "#define HAVE_SO_MAX_PACING_RATE 1" >>confdefs.h
fi
+# Check if we need -lrt for clock_gettime
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
+$as_echo_n "checking for library containing clock_gettime... " >&6; }
+if ${ac_cv_search_clock_gettime+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' rt posix4; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_clock_gettime=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_clock_gettime+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_clock_gettime+:} false; then :
+
+else
+ ac_cv_search_clock_gettime=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5
+$as_echo "$ac_cv_search_clock_gettime" >&6; }
+ac_res=$ac_cv_search_clock_gettime
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+# Check for clock_gettime support
+for ac_func in clock_gettime
+do :
+ ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
+if test "x$ac_cv_func_clock_gettime" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOCK_GETTIME 1
+_ACEOF
+
+fi
+done
+
ac_config_files="$ac_config_files Makefile src/Makefile src/version.h examples/Makefile iperf3.spec"
diff --git a/configure.ac b/configure.ac
index 800b6a6..428ed30 100644
--- a/configure.ac
+++ b/configure.ac
@@ -182,5 +182,9 @@ if test "x$iperf3_cv_header_so_max_pacing_rate" = "xyes"; then
AC_DEFINE([HAVE_SO_MAX_PACING_RATE], [1], [Have SO_MAX_PACING_RATE sockopt.])
fi
+# Check if we need -lrt for clock_gettime
+AC_SEARCH_LIBS(clock_gettime, [rt posix4])
+# Check for clock_gettime support
+AC_CHECK_FUNCS([clock_gettime])
AC_OUTPUT([Makefile src/Makefile src/version.h examples/Makefile iperf3.spec])
diff --git a/src/Makefile.am b/src/Makefile.am
index 9184e84..32a7b43 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -27,6 +27,8 @@ libiperf_la_SOURCES = \
iperf_sctp.h \
iperf_util.c \
iperf_util.h \
+ iperf_time.c \
+ iperf_time.h \
dscp.c \
net.c \
net.h \
diff --git a/src/Makefile.in b/src/Makefile.in
index 13e9d3d..a26b94e 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -142,7 +142,8 @@ libiperf_la_LIBADD =
am_libiperf_la_OBJECTS = cjson.lo iperf_api.lo iperf_error.lo \
iperf_auth.lo iperf_client_api.lo iperf_locale.lo \
iperf_server_api.lo iperf_tcp.lo iperf_udp.lo iperf_sctp.lo \
- iperf_util.lo dscp.lo net.lo tcp_info.lo timer.lo units.lo
+ iperf_util.lo iperf_time.lo dscp.lo net.lo tcp_info.lo \
+ timer.lo units.lo
libiperf_la_OBJECTS = $(am_libiperf_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -165,6 +166,7 @@ am__objects_1 = iperf3_profile-cjson.$(OBJEXT) \
iperf3_profile-iperf_udp.$(OBJEXT) \
iperf3_profile-iperf_sctp.$(OBJEXT) \
iperf3_profile-iperf_util.$(OBJEXT) \
+ iperf3_profile-iperf_time.$(OBJEXT) \
iperf3_profile-dscp.$(OBJEXT) iperf3_profile-net.$(OBJEXT) \
iperf3_profile-tcp_info.$(OBJEXT) \
iperf3_profile-timer.$(OBJEXT) iperf3_profile-units.$(OBJEXT)
@@ -220,6 +222,7 @@ am__depfiles_remade = ./$(DEPDIR)/cjson.Plo ./$(DEPDIR)/dscp.Plo \
./$(DEPDIR)/iperf3_profile-iperf_sctp.Po \
./$(DEPDIR)/iperf3_profile-iperf_server_api.Po \
./$(DEPDIR)/iperf3_profile-iperf_tcp.Po \
+ ./$(DEPDIR)/iperf3_profile-iperf_time.Po \
./$(DEPDIR)/iperf3_profile-iperf_udp.Po \
./$(DEPDIR)/iperf3_profile-iperf_util.Po \
./$(DEPDIR)/iperf3_profile-main.Po \
@@ -230,11 +233,12 @@ am__depfiles_remade = ./$(DEPDIR)/cjson.Plo ./$(DEPDIR)/dscp.Plo \
./$(DEPDIR)/iperf_auth.Plo ./$(DEPDIR)/iperf_client_api.Plo \
./$(DEPDIR)/iperf_error.Plo ./$(DEPDIR)/iperf_locale.Plo \
./$(DEPDIR)/iperf_sctp.Plo ./$(DEPDIR)/iperf_server_api.Plo \
- ./$(DEPDIR)/iperf_tcp.Plo ./$(DEPDIR)/iperf_udp.Plo \
- ./$(DEPDIR)/iperf_util.Plo ./$(DEPDIR)/net.Plo \
- ./$(DEPDIR)/t_timer-t_timer.Po ./$(DEPDIR)/t_units-t_units.Po \
- ./$(DEPDIR)/t_uuid-t_uuid.Po ./$(DEPDIR)/tcp_info.Plo \
- ./$(DEPDIR)/timer.Plo ./$(DEPDIR)/units.Plo
+ ./$(DEPDIR)/iperf_tcp.Plo ./$(DEPDIR)/iperf_time.Plo \
+ ./$(DEPDIR)/iperf_udp.Plo ./$(DEPDIR)/iperf_util.Plo \
+ ./$(DEPDIR)/net.Plo ./$(DEPDIR)/t_timer-t_timer.Po \
+ ./$(DEPDIR)/t_units-t_units.Po ./$(DEPDIR)/t_uuid-t_uuid.Po \
+ ./$(DEPDIR)/tcp_info.Plo ./$(DEPDIR)/timer.Plo \
+ ./$(DEPDIR)/units.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -619,6 +623,8 @@ libiperf_la_SOURCES = \
iperf_sctp.h \
iperf_util.c \
iperf_util.h \
+ iperf_time.c \
+ iperf_time.h \
dscp.c \
net.c \
net.h \
@@ -848,6 +854,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_sctp.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_server_api.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_tcp.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_time.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_udp.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_util.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-main.Po@am__quote@ # am--include-marker
@@ -863,6 +870,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_sctp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_server_api.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_tcp.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_time.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_udp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_util.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Plo@am__quote@ # am--include-marker
@@ -1082,6 +1090,20 @@ iperf3_profile-iperf_util.obj: iperf_util.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -c -o iperf3_profile-iperf_util.obj `if test -f 'iperf_util.c'; then $(CYGPATH_W) 'iperf_util.c'; else $(CYGPATH_W) '$(srcdir)/iperf_util.c'; fi`
+iperf3_profile-iperf_time.o: iperf_time.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -MT iperf3_profile-iperf_time.o -MD -MP -MF $(DEPDIR)/iperf3_profile-iperf_time.Tpo -c -o iperf3_profile-iperf_time.o `test -f 'iperf_time.c' || echo '$(srcdir)/'`iperf_time.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/iperf3_profile-iperf_time.Tpo $(DEPDIR)/iperf3_profile-iperf_time.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iperf_time.c' object='iperf3_profile-iperf_time.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -c -o iperf3_profile-iperf_time.o `test -f 'iperf_time.c' || echo '$(srcdir)/'`iperf_time.c
+
+iperf3_profile-iperf_time.obj: iperf_time.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -MT iperf3_profile-iperf_time.obj -MD -MP -MF $(DEPDIR)/iperf3_profile-iperf_time.Tpo -c -o iperf3_profile-iperf_time.obj `if test -f 'iperf_time.c'; then $(CYGPATH_W) 'iperf_time.c'; else $(CYGPATH_W) '$(srcdir)/iperf_time.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/iperf3_profile-iperf_time.Tpo $(DEPDIR)/iperf3_profile-iperf_time.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iperf_time.c' object='iperf3_profile-iperf_time.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -c -o iperf3_profile-iperf_time.obj `if test -f 'iperf_time.c'; then $(CYGPATH_W) 'iperf_time.c'; else $(CYGPATH_W) '$(srcdir)/iperf_time.c'; fi`
+
iperf3_profile-dscp.o: dscp.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -MT iperf3_profile-dscp.o -MD -MP -MF $(DEPDIR)/iperf3_profile-dscp.Tpo -c -o iperf3_profile-dscp.o `test -f 'dscp.c' || echo '$(srcdir)/'`dscp.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/iperf3_profile-dscp.Tpo $(DEPDIR)/iperf3_profile-dscp.Po
@@ -1632,6 +1654,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_tcp.Po
+ -rm -f ./$(DEPDIR)/iperf3_profile-iperf_time.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_udp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_util.Po
-rm -f ./$(DEPDIR)/iperf3_profile-main.Po
@@ -1647,6 +1670,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/iperf_sctp.Plo
-rm -f ./$(DEPDIR)/iperf_server_api.Plo
-rm -f ./$(DEPDIR)/iperf_tcp.Plo
+ -rm -f ./$(DEPDIR)/iperf_time.Plo
-rm -f ./$(DEPDIR)/iperf_udp.Plo
-rm -f ./$(DEPDIR)/iperf_util.Plo
-rm -f ./$(DEPDIR)/net.Plo
@@ -1714,6 +1738,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_tcp.Po
+ -rm -f ./$(DEPDIR)/iperf3_profile-iperf_time.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_udp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_util.Po
-rm -f ./$(DEPDIR)/iperf3_profile-main.Po
@@ -1729,6 +1754,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/iperf_sctp.Plo
-rm -f ./$(DEPDIR)/iperf_server_api.Plo
-rm -f ./$(DEPDIR)/iperf_tcp.Plo
+ -rm -f ./$(DEPDIR)/iperf_time.Plo
-rm -f ./$(DEPDIR)/iperf_udp.Plo
-rm -f ./$(DEPDIR)/iperf_util.Plo
-rm -f ./$(DEPDIR)/net.Plo
diff --git a/src/iperf.h b/src/iperf.h
index 5c36123..26e4f4f 100755
--- a/src/iperf.h
+++ b/src/iperf.h
@@ -61,6 +61,7 @@
#include "timer.h"
#include "queue.h"
#include "cjson.h"
+#include "iperf_time.h"
#if defined(HAVE_SSL)
#include <openssl/bio.h>
@@ -72,8 +73,8 @@ typedef uint64_t iperf_size_t;
struct iperf_interval_results
{
iperf_size_t bytes_transferred; /* bytes transfered in this interval */
- struct timeval interval_start_time;
- struct timeval interval_end_time;
+ struct iperf_time interval_start_time;
+ struct iperf_time interval_end_time;
float interval_duration;
/* for UDP */
@@ -119,9 +120,9 @@ struct iperf_stream_result
int stream_sum_rtt;
int stream_count_rtt;
int stream_max_snd_cwnd;
- struct timeval start_time;
- struct timeval end_time;
- struct timeval start_time_fixed;
+ struct iperf_time start_time;
+ struct iperf_time end_time;
+ struct iperf_time start_time_fixed;
double sender_time;
double receiver_time;
TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results;
diff --git a/src/iperf_api.c b/src/iperf_api.c
index 9af71c3..1046526 100755
--- a/src/iperf_api.c
+++ b/src/iperf_api.c
@@ -1246,14 +1246,16 @@ iperf_set_send_state(struct iperf_test *test, signed char state)
}
void
-iperf_check_throttle(struct iperf_stream *sp, struct timeval *nowP)
+iperf_check_throttle(struct iperf_stream *sp, struct iperf_time *nowP)
{
+ struct iperf_time temp_time;
double seconds;
uint64_t bits_per_second;
if (sp->test->done)
return;
- seconds = timeval_diff(&sp->result->start_time_fixed, nowP);
+ iperf_time_diff(&sp->result->start_time_fixed, nowP, &temp_time);
+ seconds = iperf_time_in_secs(&temp_time);
bits_per_second = sp->result->bytes_sent * 8 / seconds;
if (bits_per_second < sp->test->settings->rate) {
sp->green_light = 1;
@@ -1269,7 +1271,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
{
register int multisend, r, streams_active;
register struct iperf_stream *sp;
- struct timeval now;
+ struct iperf_time now;
/* Can we do multisend mode? */
if (test->settings->burst != 0)
@@ -1281,7 +1283,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
for (; multisend > 0; --multisend) {
if (test->settings->rate != 0 && test->settings->burst == 0)
- gettimeofday(&now, NULL);
+ iperf_time_now(&now);
streams_active = 0;
SLIST_FOREACH(sp, &test->streams, streams) {
if ((sp->green_light &&
@@ -1307,7 +1309,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
break;
}
if (test->settings->burst != 0) {
- gettimeofday(&now, NULL);
+ iperf_time_now(&now);
SLIST_FOREACH(sp, &test->streams, streams)
iperf_check_throttle(sp, &now);
}
@@ -1343,7 +1345,7 @@ iperf_recv(struct iperf_test *test, fd_set *read_setP)
int
iperf_init_test(struct iperf_test *test)
{
- struct timeval now;
+ struct iperf_time now;
struct iperf_stream *sp;
if (test->protocol->init) {
@@ -1352,7 +1354,7 @@ iperf_init_test(struct iperf_test *test)
}
/* Init each stream. */
- if (gettimeofday(&now, NULL) < 0) {
+ if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST;
return -1;
}
@@ -1367,7 +1369,7 @@ iperf_init_test(struct iperf_test *test)
}
static void
-send_timer_proc(TimerClientData client_data, struct timeval *nowP)
+send_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
{
struct iperf_stream *sp = client_data.p;
@@ -1381,11 +1383,11 @@ send_timer_proc(TimerClientData client_data, struct timeval *nowP)
int
iperf_create_send_timers(struct iperf_test * test)
{
- struct timeval now;
+ struct iperf_time now;
struct iperf_stream *sp;
TimerClientData cd;
- if (gettimeofday(&now, NULL) < 0) {
+ if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST;
return -1;
}
@@ -1393,7 +1395,7 @@ iperf_create_send_timers(struct iperf_test * test)
sp->green_light = 1;
if (test->settings->rate != 0) {
cd.p = sp;
- sp->send_timer = tmr_create((struct timeval*) 0, send_timer_proc, cd, test->settings->pacing_timer, 1);
+ sp->send_timer = tmr_create(NULL, send_timer_proc, cd, test->settings->pacing_timer, 1);
if (sp->send_timer == NULL) {
i_errno = IEINITTEST;
return -1;
@@ -1689,6 +1691,7 @@ send_results(struct iperf_test *test)
int sender_has_retransmits;
iperf_size_t bytes_transferred;
int retransmits;
+ struct iperf_time temp_time;
double start_time, end_time;
j = cJSON_CreateObject();
@@ -1758,8 +1761,10 @@ send_results(struct iperf_test *test)
cJSON_AddNumberToObject(j_stream, "errors", sp->cnt_error);
cJSON_AddNumberToObject(j_stream, "packets", sp->packet_count);
- start_time = timeval_diff(&sp->result->start_time, &sp->result->start_time);
- end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time);
+ iperf_time_diff(&sp->result->start_time, &sp->result->start_time, &temp_time);
+ start_time = iperf_time_in_secs(&temp_time);
+ iperf_time_diff(&sp->result->start_time, &sp->result->end_time, &temp_time);
+ end_time = iperf_time_in_secs(&temp_time);
cJSON_AddNumberToObject(j_stream, "start_time", start_time);
cJSON_AddNumberToObject(j_stream, "end_time", end_time);
@@ -2430,13 +2435,13 @@ iperf_reset_test(struct iperf_test *test)
void
iperf_reset_stats(struct iperf_test *test)
{
- struct timeval now;
+ struct iperf_time now;
struct iperf_stream *sp;
struct iperf_stream_result *rp;
test->bytes_sent = 0;
test->blocks_sent = 0;
- gettimeofday(&now, NULL);
+ iperf_time_now(&now);
SLIST_FOREACH(sp, &test->streams, streams) {
sp->omitted_packet_count = sp->packet_count;
sp->omitted_cnt_error = sp->cnt_error;
@@ -2469,6 +2474,7 @@ iperf_stats_callback(struct iperf_test *test)
struct iperf_stream *sp;
struct iperf_stream_result *rp = NULL;
struct iperf_interval_results *irp, temp;
+ struct iperf_time temp_time;
temp.omitted = test->omitting;
SLIST_FOREACH(sp, &test->streams, streams) {
@@ -2479,14 +2485,14 @@ iperf_stats_callback(struct iperf_test *test)
irp = TAILQ_LAST(&rp->interval_results, irlisthead);
/* result->end_time contains timestamp of previous interval */
if ( irp != NULL ) /* not the 1st interval */
- memcpy(&temp.interval_start_time, &rp->end_time, sizeof(struct timeval));
+ memcpy(&temp.interval_start_time, &rp->end_time, sizeof(struct iperf_time));
else /* or use timestamp from beginning */
- memcpy(&temp.interval_start_time, &rp->start_time, sizeof(struct timeval));
+ memcpy(&temp.interval_start_time, &rp->start_time, sizeof(struct iperf_time));
/* now save time of end of this interval */
- gettimeofday(&rp->end_time, NULL);
- memcpy(&temp.interval_end_time, &rp->end_time, sizeof(struct timeval));
- temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time);
- //temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time);
+ iperf_time_now(&rp->end_time);
+ memcpy(&temp.interval_end_time, &rp->end_time, sizeof(struct iperf_time));
+ iperf_time_diff(&temp.interval_start_time, &temp.interval_end_time, &temp_time);
+ temp.interval_duration = iperf_time_in_secs(&temp_time);
if (test->protocol->id == Ptcp) {
if ( has_tcpinfo()) {
save_tcpinfo(sp, &temp);
@@ -2553,6 +2559,7 @@ iperf_print_intermediate(struct iperf_test *test)
double bandwidth;
int retransmits = 0;
double start_time, end_time;
+ struct iperf_time temp_time;
cJSON *json_interval;
cJSON *json_interval_streams;
int total_packets = 0, lost_packets = 0;
@@ -2575,8 +2582,8 @@ iperf_print_intermediate(struct iperf_test *test)
SLIST_FOREACH(sp, &test->streams, streams) {
irp = TAILQ_LAST(&sp->result->interval_results, irlisthead);
if (irp) {
- double interval_len = timeval_diff(&irp->interval_start_time,
- &irp->interval_end_time);
+ iperf_time_diff(&irp->interval_start_time, &irp->interval_end_time, &temp_time);
+ double interval_len = iperf_time_in_secs(&temp_time);
if (test->debug) {
printf("interval_len %f bytes_transferred %" PRIu64 "\n", interval_len, irp->bytes_transferred);
}
@@ -2641,14 +2648,16 @@ iperf_print_intermediate(struct iperf_test *test)
sp = SLIST_FIRST(&test->streams); /* reset back to 1st stream */
/* Only do this of course if there was a first stream */
if (sp) {
- irp = TAILQ_LAST(&sp->result->interval_results, irlisthead); /* use 1st stream for timing info */
+ irp = TAILQ_LAST(&sp->result->interval_results, irlisthead); /* use 1st stream for timing info */
- unit_snprintf(ubuf, UNIT_LEN, (double) bytes, 'A');
- bandwidth = (double) bytes / (double) irp->interval_duration;
- unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
+ unit_snprintf(ubuf, UNIT_LEN, (double) bytes, 'A');
+ bandwidth = (double) bytes / (double) irp->interval_duration;
+ unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
- start_time = timeval_diff(&sp->result->start_time,&irp->interval_start_time);
- end_time = timeval_diff(&sp->result->start_time,&irp->interval_end_time);
+ iperf_time_diff(&sp->result->start_time,&irp->interval_start_time, &temp_time);
+ start_time = iperf_time_in_secs(&temp_time);
+ iperf_time_diff(&sp->result->start_time,&irp->interval_end_time, &temp_time);
+ end_time = iperf_time_in_secs(&temp_time);
if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
if (test->sender && test->sender_has_retransmits) {
/* Interval sum, TCP with retransmits. */
@@ -2710,6 +2719,7 @@ iperf_print_results(struct iperf_test *test)
iperf_size_t bytes_received, total_received = 0;
double start_time, end_time = 0.0, avg_jitter = 0.0, lost_percent = 0.0;
double sender_time = 0.0, receiver_time = 0.0;
+ struct iperf_time temp_time;
double bandwidth;
/* print final summary for all intervals */
@@ -2747,7 +2757,8 @@ iperf_print_results(struct iperf_test *test)
* basically emulating what iperf 3.1 did.
*/
if (sp) {
- end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time);
+ iperf_time_diff(&sp->result->start_time, &sp->result->end_time, &temp_time);
+ end_time = iperf_time_in_secs(&temp_time);
if (test->sender) {
sp->result->sender_time = end_time;
if (sp->result->receiver_time == 0.0) {
@@ -3142,6 +3153,7 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
char nbuf[UNIT_LEN];
char cbuf[UNIT_LEN];
double st = 0., et = 0.;
+ struct iperf_time temp_time;
struct iperf_interval_results *irp = NULL;
double bandwidth, lost_percent;
@@ -3157,7 +3169,7 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
** else if there's more than one stream, print the separator;
** else nothing.
*/
- if (timeval_equals(&sp->result->start_time, &irp->interval_start_time)) {
+ if (iperf_time_compare(&sp->result->start_time, &irp->interval_start_time) == 0) {
if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
if (test->sender && test->sender_has_retransmits)
iperf_printf(test, "%s", report_bw_retrans_cwnd_header);
@@ -3183,8 +3195,10 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
}
unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
- st = timeval_diff(&sp->result->start_time, &irp->interval_start_time);
- et = timeval_diff(&sp->result->start_time, &irp->interval_end_time);
+ iperf_time_diff(&sp->result->start_time, &irp->interval_start_time, &temp_time);
+ st = iperf_time_in_secs(&temp_time);
+ iperf_time_diff(&sp->result->start_time, &irp->interval_end_time, &temp_time);
+ et = iperf_time_in_secs(&temp_time);
if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
if (test->sender && test->sender_has_retransmits) {
diff --git a/src/iperf_api.h b/src/iperf_api.h
index 53012c0..f0818bd 100755
--- a/src/iperf_api.h
+++ b/src/iperf_api.h
@@ -42,6 +42,7 @@ struct iperf_test;
struct iperf_stream_result;
struct iperf_interval_results;
struct iperf_stream;
+struct iperf_time;
/* default settings */
#define Ptcp SOCK_STREAM
@@ -240,7 +241,7 @@ void print_tcpinfo(struct iperf_test *test);
void build_tcpinfo_message(struct iperf_interval_results *r, char *message);
int iperf_set_send_state(struct iperf_test *test, signed char state);
-void iperf_check_throttle(struct iperf_stream *sp, struct timeval *nowP);
+void iperf_check_throttle(struct iperf_stream *sp, struct iperf_time *nowP);
int iperf_send(struct iperf_test *, fd_set *) /* __attribute__((hot)) */;
int iperf_recv(struct iperf_test *, fd_set *);
void iperf_catch_sigend(void (*handler)(int));
diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c
index c823c5a..30fa2ac 100644
--- a/src/iperf_client_api.c
+++ b/src/iperf_client_api.c
@@ -41,6 +41,7 @@
#include "iperf_api.h"
#include "iperf_util.h"
#include "iperf_locale.h"
+#include "iperf_time.h"
#include "net.h"
#include "timer.h"
@@ -116,7 +117,7 @@ iperf_create_streams(struct iperf_test *test)
}
static void
-test_timer_proc(TimerClientData client_data, struct timeval *nowP)
+test_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
{
struct iperf_test *test = client_data.p;
@@ -125,7 +126,7 @@ test_timer_proc(TimerClientData client_data, struct timeval *nowP)
}
static void
-client_stats_timer_proc(TimerClientData client_data, struct timeval *nowP)
+client_stats_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
{
struct iperf_test *test = client_data.p;
@@ -136,7 +137,7 @@ client_stats_timer_proc(TimerClientData client_data, struct timeval *nowP)
}
static void
-client_reporter_timer_proc(TimerClientData client_data, struct timeval *nowP)
+client_reporter_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
{
struct iperf_test *test = client_data.p;
@@ -149,10 +150,10 @@ client_reporter_timer_proc(TimerClientData client_data, struct timeval *nowP)
static int
create_client_timers(struct iperf_test * test)
{
- struct timeval now;
+ struct iperf_time now;
TimerClientData cd;
- if (gettimeofday(&now, NULL) < 0) {
+ if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST;
return -1;
}
@@ -184,7 +185,7 @@ create_client_timers(struct iperf_test * test)
}
static void
-client_omit_timer_proc(TimerClientData client_data, struct timeval *nowP)
+client_omit_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
{
struct iperf_test *test = client_data.p;
@@ -204,14 +205,14 @@ client_omit_timer_proc(TimerClientData client_data, struct timeval *nowP)
static int
create_client_omit_timer(struct iperf_test * test)
{
- struct timeval now;
+ struct iperf_time now;
TimerClientData cd;
if (test->omit == 0) {
test->omit_timer = NULL;
test->omitting = 0;
} else {
- if (gettimeofday(&now, NULL) < 0) {
+ if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST;
return -1;
}
@@ -442,7 +443,7 @@ iperf_run_client(struct iperf_test * test)
int startup;
int result = 0;
fd_set read_set, write_set;
- struct timeval now;
+ struct iperf_time now;
struct timeval* timeout = NULL;
struct iperf_stream *sp;
@@ -475,7 +476,7 @@ iperf_run_client(struct iperf_test * test)
while (test->state != IPERF_DONE) {
memcpy(&read_set, &test->read_set, sizeof(fd_set));
memcpy(&write_set, &test->write_set, sizeof(fd_set));
- (void) gettimeofday(&now, NULL);
+ iperf_time_now(&now);
timeout = tmr_timeout(&now);
result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout);
if (result < 0 && errno != EINTR) {
@@ -516,7 +517,7 @@ iperf_run_client(struct iperf_test * test)
}
/* Run the timers. */
- (void) gettimeofday(&now, NULL);
+ iperf_time_now(&now);
tmr_run(&now);
/* Is the test done yet? */
diff --git a/src/iperf_config.h.in b/src/iperf_config.h.in
index 2d13f98..e543cbd 100644
--- a/src/iperf_config.h.in
+++ b/src/iperf_config.h.in
@@ -1,5 +1,8 @@
/* src/iperf_config.h.in. Generated from configure.ac by autoheader. */
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
/* Define to 1 if you have the `cpuset_setaffinity' function. */
#undef HAVE_CPUSET_SETAFFINITY
diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c
index 5fa1dd7..272db82 100644
--- a/src/iperf_server_api.c
+++ b/src/iperf_server_api.c
@@ -54,6 +54,7 @@
#include "iperf_tcp.h"
#include "iperf_util.h"
#include "timer.h"
+#include "iperf_time.h"
#include "net.h"
#include "units.h"
#include "iperf_util.h"
@@ -223,7 +224,7 @@ iperf_handle_message_server(struct iperf_test *test)
}
static void
-server_timer_proc(TimerClientData client_data, struct timeval *nowP)
+server_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
{
struct iperf_test *test = client_data.p;
struct iperf_stream *sp;
@@ -243,7 +244,7 @@ server_timer_proc(TimerClientData client_data, struct timeval *nowP)
}
static void
-server_stats_timer_proc(TimerClientData client_data, struct timeval *nowP)
+server_stats_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
{
struct iperf_test *test = client_data.p;
@@ -254,7 +255,7 @@ server_stats_timer_proc(TimerClientData client_data, struct timeval *nowP)
}
static void
-server_reporter_timer_proc(TimerClientData client_data, struct timeval *nowP)
+server_reporter_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
{
struct iperf_test *test = client_data.p;
@@ -267,10 +268,10 @@ server_reporter_timer_proc(TimerClientData client_data, struct timeval *nowP)
static int
create_server_timers(struct iperf_test * test)
{
- struct timeval now;
+ struct iperf_time now;
TimerClientData cd;
- if (gettimeofday(&now, NULL) < 0) {
+ if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST;
return -1;
}
@@ -304,7 +305,7 @@ create_server_timers(struct iperf_test * test)
}
static void
-server_omit_timer_proc(TimerClientData client_data, struct timeval *nowP)
+server_omit_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
{
struct iperf_test *test = client_data.p;
@@ -324,14 +325,14 @@ server_omit_timer_proc(TimerClientData client_data, struct timeval *nowP)
static int
create_server_omit_timer(struct iperf_test * test)
{
- struct timeval now;
+ struct iperf_time now;
TimerClientData cd;
if (test->omit == 0) {
test->omit_timer = NULL;
test->omitting = 0;
} else {
- if (gettimeofday(&now, NULL) < 0) {
+ if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST;
return -1;
}
@@ -391,7 +392,7 @@ iperf_run_server(struct iperf_test *test)
#endif /* HAVE_TCP_CONGESTION */
fd_set read_set, write_set;
struct iperf_stream *sp;
- struct timeval now;
+ struct iperf_time now;
struct timeval* timeout;
if (test->affinity != -1)
@@ -428,7 +429,7 @@ iperf_run_server(struct iperf_test *test)
memcpy(&read_set, &test->read_set, sizeof(fd_set));
memcpy(&write_set, &test->write_set, sizeof(fd_set));
- (void) gettimeofday(&now, NULL);
+ iperf_time_now(&now);
timeout = tmr_timeout(&now);
result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout);
if (result < 0 && errno != EINTR) {
@@ -606,7 +607,7 @@ iperf_run_server(struct iperf_test *test)
if (result == 0 ||
(timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)) {
/* Run the timers. */
- (void) gettimeofday(&now, NULL);
+ iperf_time_now(&now);
tmr_run(&now);
}
}
diff --git a/src/iperf_time.c b/src/iperf_time.c
new file mode 100644
index 0000000..0ca3790
--- /dev/null
+++ b/src/iperf_time.c
@@ -0,0 +1,156 @@
+/*
+ * iperf, Copyright (c) 2014-2018, The Regents of the University of
+ * California, through Lawrence Berkeley National Laboratory (subject
+ * to receipt of any required approvals from the U.S. Dept. of
+ * Energy). All rights reserved.
+ *
+ * If you have questions about your rights to use or distribute this
+ * software, please contact Berkeley Lab's Technology Transfer
+ * Department at TTD@lbl.gov.
+ *
+ * NOTICE. This software is owned by the U.S. Department of Energy.
+ * As such, the U.S. Government has been granted for itself and others
+ * acting on its behalf a paid-up, nonexclusive, irrevocable,
+ * worldwide license in the Software to reproduce, prepare derivative
+ * works, and perform publicly and display publicly. Beginning five
+ * (5) years after the date permission to assert copyright is obtained
+ * from the U.S. Department of Energy, and subject to any subsequent
+ * five (5) year renewals, the U.S. Government is granted for itself
+ * and others acting on its behalf a paid-up, nonexclusive,
+ * irrevocable, worldwide license in the Software to reproduce,
+ * prepare derivative works, distribute copies to the public, perform
+ * publicly and display publicly, and to permit others to do so.
+ *
+ * This code is distributed under a BSD style license, see the LICENSE
+ * file for complete information.
+ */
+
+
+#include <stddef.h>
+
+#include "iperf_config.h"
+#include "iperf_time.h"
+
+#ifdef HAVE_CLOCK_GETTIME
+
+#include <time.h>
+
+int
+iperf_time_now(struct iperf_time *time1)
+{
+ struct timespec ts;
+ int result;
+ result = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+ if (result == 0) {
+ time1->secs = (uint32_t) ts.tv_sec;
+ time1->usecs = (uint32_t) ts.tv_nsec / 1000;
+ }
+ return result;
+}
+
+#else
+
+#include <sys/time.h>
+
+int
+iperf_time_now(struct iperf_time *time1)
+{
+ struct timeval tv;
+ int result;
+ result = gettimeofday(&tv, NULL);
+ time1->secs = tv.tv_sec;
+ time1->usecs = tv.tv_usec;
+ return result;
+}
+
+#endif
+
+/* iperf_time_add_usecs
+ *
+ * Add a number of microseconds to a iperf_time.
+ */
+void
+iperf_time_add_usecs(struct iperf_time *time1, uint64_t usecs)
+{
+ time1->secs += usecs / 1000000L;
+ time1->usecs += usecs % 1000000L;
+ if ( time1->usecs >= 1000000L ) {
+ time1->secs += time1->usecs / 1000000L;
+ time1->usecs %= 1000000L;
+ }
+}
+
+uint64_t
+iperf_time_in_usecs(struct iperf_time *time)
+{
+ return time->secs * 1000000LL + time->usecs;
+}
+
+double
+iperf_time_in_secs(struct iperf_time *time)
+{
+ return time->secs + time->usecs / 1000000.0;
+}
+
+/* iperf_time_compare
+ *
+ * Compare two timestamps
+ *
+ * Returns -1 if time1 is earlier, 1 if time1 is later,
+ * or 0 if the timestamps are equal.
+ */
+int
+iperf_time_compare(struct iperf_time *time1, struct iperf_time *time2)
+{
+ if (time1->secs < time2->secs)
+ return -1;
+ if (time1->secs > time2->secs)
+ return 1;
+ if (time1->usecs < time2->usecs)
+ return -1;
+ if (time1->usecs > time2->usecs)
+ return 1;
+ return 0;
+}
+
+/* iperf_time_diff
+ *
+ * Calculates the time from time2 to time1, assuming time1 is later than time2.
+ * The diff will always be positive, so the return value should be checked
+ * to determine if time1 was earlier than time2.
+ *
+ * Returns 1 if the time1 is less than or equal to time2, otherwise 0.
+ */
+int
+iperf_time_diff(struct iperf_time *time1, struct iperf_time *time2, struct iperf_time *diff)
+{
+ int past = 0;
+ int cmp = 0;
+
+ cmp = iperf_time_compare(time1, time2);
+ if (cmp == 0) {
+ diff->secs = 0;
+ diff->usecs = 0;
+ past = 1;
+ }
+ else if (cmp == 1) {
+ diff->secs = time1->secs - time2->secs;
+ diff->usecs = time1->usecs;
+ if (diff->usecs < time2->usecs) {
+ diff->secs -= 1;
+ diff->usecs += 1000000;
+ }
+ diff->usecs = diff->usecs - time2->usecs;
+ } else {
+ diff->secs = time2->secs - time1->secs;
+ diff->usecs = time2->usecs;
+ if (diff->usecs < time1->usecs) {
+ diff->secs -= 1;
+ diff->usecs += 1000000;
+ }
+ diff->usecs = diff->usecs - time1->usecs;
+ past = 1;
+ }
+
+ return past;
+}
diff --git a/src/iperf_time.h b/src/iperf_time.h
new file mode 100644
index 0000000..588ee26
--- /dev/null
+++ b/src/iperf_time.h
@@ -0,0 +1,49 @@
+/*
+ * iperf, Copyright (c) 2014-2018, The Regents of the University of
+ * California, through Lawrence Berkeley National Laboratory (subject
+ * to receipt of any required approvals from the U.S. Dept. of
+ * Energy). All rights reserved.
+ *
+ * If you have questions about your rights to use or distribute this
+ * software, please contact Berkeley Lab's Technology Transfer
+ * Department at TTD@lbl.gov.
+ *
+ * NOTICE. This software is owned by the U.S. Department of Energy.
+ * As such, the U.S. Government has been granted for itself and others
+ * acting on its behalf a paid-up, nonexclusive, irrevocable,
+ * worldwide license in the Software to reproduce, prepare derivative
+ * works, and perform publicly and display publicly. Beginning five
+ * (5) years after the date permission to assert copyright is obtained
+ * from the U.S. Department of Energy, and subject to any subsequent
+ * five (5) year renewals, the U.S. Government is granted for itself
+ * and others acting on its behalf a paid-up, nonexclusive,
+ * irrevocable, worldwide license in the Software to reproduce,
+ * prepare derivative works, distribute copies to the public, perform
+ * publicly and display publicly, and to permit others to do so.
+ *
+ * This code is distributed under a BSD style license, see the LICENSE
+ * file for complete information.
+ */
+#ifndef __IPERF_TIME_H
+#define __IPERF_TIME_H
+
+#include <stdint.h>
+
+struct iperf_time {
+ uint32_t secs;
+ uint32_t usecs;
+};
+
+int iperf_time_now(struct iperf_time *time1);
+
+void iperf_time_add_usecs(struct iperf_time *time1, uint64_t usecs);
+
+int iperf_time_compare(struct iperf_time *time1, struct iperf_time *time2);
+
+int iperf_time_diff(struct iperf_time *time1, struct iperf_time *time2, struct iperf_time *diff);
+
+uint64_t iperf_time_in_usecs(struct iperf_time *time);
+
+double iperf_time_in_secs(struct iperf_time *time);
+
+#endif
diff --git a/src/iperf_udp.c b/src/iperf_udp.c
index 33f367f..3d37dab 100644
--- a/src/iperf_udp.c
+++ b/src/iperf_udp.c
@@ -66,7 +66,7 @@ iperf_udp_recv(struct iperf_stream *sp)
int r;
int size = sp->settings->blksize;
double transit = 0, d = 0;
- struct timeval sent_time, arrival_time;
+ struct iperf_time sent_time, arrival_time, temp_time;
r = Nread(sp->socket, sp->buffer, size, Pudp);
@@ -90,8 +90,8 @@ iperf_udp_recv(struct iperf_stream *sp)
sec = ntohl(sec);
usec = ntohl(usec);
pcount = be64toh(pcount);
- sent_time.tv_sec = sec;
- sent_time.tv_usec = usec;
+ sent_time.secs = sec;
+ sent_time.usecs = usec;
}
else {
uint32_t pc;
@@ -101,8 +101,8 @@ iperf_udp_recv(struct iperf_stream *sp)
sec = ntohl(sec);
usec = ntohl(usec);
pcount = ntohl(pc);
- sent_time.tv_sec = sec;
- sent_time.tv_usec = usec;
+ sent_time.secs = sec;
+ sent_time.usecs = usec;
}
if (sp->test->debug)
@@ -163,9 +163,10 @@ iperf_udp_recv(struct iperf_stream *sp)
* computation does not require knowing the round-trip
* time.
*/
- gettimeofday(&arrival_time, NULL);
+ iperf_time_now(&arrival_time);
- transit = timeval_diff(&sent_time, &arrival_time);
+ iperf_time_diff(&arrival_time, &sent_time, &temp_time);
+ transit = iperf_time_in_secs(&temp_time);
d = transit - sp->prev_transit;
if (d < 0)
d = -d;
@@ -190,9 +191,9 @@ iperf_udp_send(struct iperf_stream *sp)
{
int r;
int size = sp->settings->blksize;
- struct timeval before;
+ struct iperf_time before;
- gettimeofday(&before, 0);
+ iperf_time_now(&before);
++sp->packet_count;
@@ -201,8 +202,8 @@ iperf_udp_send(struct iperf_stream *sp)
uint32_t sec, usec;
uint64_t pcount;
- sec = htonl(before.tv_sec);
- usec = htonl(before.tv_usec);
+ sec = htonl(before.secs);
+ usec = htonl(before.usecs);
pcount = htobe64(sp->packet_count);
memcpy(sp->buffer, &sec, sizeof(sec));
@@ -214,8 +215,8 @@ iperf_udp_send(struct iperf_stream *sp)
uint32_t sec, usec, pcount;
- sec = htonl(before.tv_sec);
- usec = htonl(before.tv_usec);
+ sec = htonl(before.secs);
+ usec = htonl(before.usecs);
pcount = htonl(sp->packet_count);
memcpy(sp->buffer, &sec, sizeof(sec));
diff --git a/src/iperf_util.c b/src/iperf_util.c
index 3922def..c5af476 100644
--- a/src/iperf_util.c
+++ b/src/iperf_util.c
@@ -189,10 +189,10 @@ timeval_diff(struct timeval * tv0, struct timeval * tv1)
void
cpu_util(double pcpu[3])
{
- static struct timeval last;
+ static struct iperf_time last;
static clock_t clast;
static struct rusage rlast;
- struct timeval temp;
+ struct iperf_time now, temp_time;
clock_t ctemp;
struct rusage rtemp;
double timediff;
@@ -200,18 +200,19 @@ cpu_util(double pcpu[3])
double systemdiff;
if (pcpu == NULL) {
- gettimeofday(&last, NULL);
+ iperf_time_now(&last);
clast = clock();
getrusage(RUSAGE_SELF, &rlast);
return;
}
- gettimeofday(&temp, NULL);
+ iperf_time_now(&now);
ctemp = clock();
getrusage(RUSAGE_SELF, &rtemp);
- timediff = ((temp.tv_sec * 1000000.0 + temp.tv_usec) -
- (last.tv_sec * 1000000.0 + last.tv_usec));
+ iperf_time_diff(&now, &last, &temp_time);
+ timediff = iperf_time_in_secs(&temp_time);
+
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) -
diff --git a/src/t_timer.c b/src/t_timer.c
index ed74672..9598594 100644
--- a/src/t_timer.c
+++ b/src/t_timer.c
@@ -35,13 +35,14 @@
#include <sys/time.h>
#include "timer.h"
+#include "iperf_time.h"
static int flag;
static void
-timer_proc( TimerClientData client_data, struct timeval* nowP )
+timer_proc( TimerClientData client_data, struct iperf_time* nowP )
{
flag = 1;
}
@@ -53,7 +54,7 @@ main(int argc, char **argv)
Timer *tp;
flag = 0;
- tp = tmr_create((struct timeval*) 0, timer_proc, JunkClientData, 3000000, 0);
+ tp = tmr_create(NULL, timer_proc, JunkClientData, 3000000, 0);
if (!tp)
{
printf("failed to create timer\n");
@@ -62,7 +63,7 @@ main(int argc, char **argv)
sleep(2);
- tmr_run((struct timeval*) 0);
+ tmr_run(NULL);
if (flag)
{
printf("timer should not have expired\n");
@@ -70,7 +71,7 @@ main(int argc, char **argv)
}
sleep(1);
- tmr_run((struct timeval*) 0);
+ tmr_run(NULL);
if (!flag)
{
printf("timer should have expired\n");
diff --git a/src/timer.c b/src/timer.c
index bfc52e4..33923c7 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -31,7 +31,7 @@
#include <stdlib.h>
#include "timer.h"
-
+#include "iperf_time.h"
static Timer* timers = NULL;
static Timer* free_timers = NULL;
@@ -41,19 +41,19 @@ TimerClientData JunkClientData;
/* This is an efficiency tweak. All the routines that need to know the
-** current time get passed a pointer to a struct timeval. If it's non-NULL
-** it gets used, otherwise we do our own gettimeofday() to fill it in.
-** This lets the caller avoid extraneous gettimeofday()s when efficiency
+** current time get passed a pointer to a struct iperf_time. If it's non-NULL
+** it gets used, otherwise we do our own iperf_time_now() to fill it in.
+** This lets the caller avoid extraneous iperf_time_now()s when efficiency
** is needed, and not bother with the extra code when efficiency doesn't
** matter too much.
*/
static void
-getnow( struct timeval* nowP, struct timeval* nowP2 )
+getnow( struct iperf_time* nowP, struct iperf_time* nowP2 )
{
if ( nowP != NULL )
*nowP2 = *nowP;
else
- (void) gettimeofday( nowP2, NULL );
+ iperf_time_now(nowP2);
}
@@ -68,9 +68,7 @@ list_add( Timer* t )
timers = t;
t->prev = t->next = NULL;
} else {
- if ( t->time.tv_sec < timers->time.tv_sec ||
- ( t->time.tv_sec == timers->time.tv_sec &&
- t->time.tv_usec < timers->time.tv_usec ) ) {
+ if (iperf_time_compare(&t->time, &timers->time) < 0) {
/* The new timer goes at the head of the list. */
t->prev = NULL;
t->next = timers;
@@ -80,9 +78,7 @@ list_add( Timer* t )
/* Walk the list to find the insertion point. */
for ( t2prev = timers, t2 = timers->next; t2 != NULL;
t2prev = t2, t2 = t2->next ) {
- if ( t->time.tv_sec < t2->time.tv_sec ||
- ( t->time.tv_sec == t2->time.tv_sec &&
- t->time.tv_usec < t2->time.tv_usec ) ) {
+ if (iperf_time_compare(&t->time, &t2->time) < 0) {
/* Found it. */
t2prev->next = t;
t->prev = t2prev;
@@ -122,24 +118,12 @@ list_resort( Timer* t )
}
-static void
-add_usecs( struct timeval* t, int64_t usecs )
-{
- t->tv_sec += usecs / 1000000L;
- t->tv_usec += usecs % 1000000L;
- if ( t->tv_usec >= 1000000L ) {
- t->tv_sec += t->tv_usec / 1000000L;
- t->tv_usec %= 1000000L;
- }
-}
-
-
Timer*
tmr_create(
- struct timeval* nowP, TimerProc* timer_proc, TimerClientData client_data,
+ struct iperf_time* nowP, TimerProc* timer_proc, TimerClientData client_data,
int64_t usecs, int periodic )
{
- struct timeval now;
+ struct iperf_time now;
Timer* t;
getnow( nowP, &now );
@@ -158,7 +142,7 @@ tmr_create(
t->usecs = usecs;
t->periodic = periodic;
t->time = now;
- add_usecs( &t->time, usecs );
+ iperf_time_add_usecs(&t->time, usecs);
/* Add the new timer to the active list. */
list_add( t );
@@ -167,20 +151,22 @@ tmr_create(
struct timeval*
-tmr_timeout( struct timeval* nowP )
+tmr_timeout( struct iperf_time* nowP )
{
- struct timeval now;
+ struct iperf_time now, diff;
int64_t usecs;
+ int past;
static struct timeval timeout;
getnow( nowP, &now );
/* Since the list is sorted, we only need to look at the first timer. */
if ( timers == NULL )
return NULL;
- usecs = ( timers->time.tv_sec - now.tv_sec ) * 1000000LL +
- ( timers->time.tv_usec - now.tv_usec );
- if ( usecs <= 0 )
- usecs = 0;
+ past = iperf_time_diff(&timers->time, &now, &diff);
+ if (past)
+ usecs = 0;
+ else
+ usecs = iperf_time_in_usecs(&diff);
timeout.tv_sec = usecs / 1000000LL;
timeout.tv_usec = usecs % 1000000LL;
return &timeout;
@@ -188,9 +174,9 @@ tmr_timeout( struct timeval* nowP )
void
-tmr_run( struct timeval* nowP )
+tmr_run( struct iperf_time* nowP )
{
- struct timeval now;
+ struct iperf_time now;
Timer* t;
Timer* next;
@@ -200,14 +186,12 @@ tmr_run( struct timeval* nowP )
/* Since the list is sorted, as soon as we find a timer
** that isn't ready yet, we are done.
*/
- if ( t->time.tv_sec > now.tv_sec ||
- ( t->time.tv_sec == now.tv_sec &&
- t->time.tv_usec > now.tv_usec ) )
+ if (iperf_time_compare(&t->time, &now) > 0)
break;
(t->timer_proc)( t->client_data, &now );
if ( t->periodic ) {
/* Reschedule. */
- add_usecs( &t->time, t->usecs );
+ iperf_time_add_usecs(&t->time, t->usecs);
list_resort( t );
} else
tmr_cancel( t );
@@ -216,13 +200,13 @@ tmr_run( struct timeval* nowP )
void
-tmr_reset( struct timeval* nowP, Timer* t )
+tmr_reset( struct iperf_time* nowP, Timer* t )
{
- struct timeval now;
+ struct iperf_time now;
getnow( nowP, &now );
t->time = now;
- add_usecs( &t->time, t->usecs );
+ iperf_time_add_usecs( &t->time, t->usecs );
list_resort( t );
}
diff --git a/src/timer.h b/src/timer.h
index 0f9c5eb..301cdf3 100644
--- a/src/timer.h
+++ b/src/timer.h
@@ -30,7 +30,8 @@
#ifndef __TIMER_H
#define __TIMER_H
-#include <sys/time.h>
+#include <time.h>
+#include "iperf_time.h"
/* TimerClientData is an opaque value that tags along with a timer. The
** client can use it for whatever, and it gets passed to the callback when
@@ -46,10 +47,10 @@ typedef union
extern TimerClientData JunkClientData; /* for use when you don't care */
/* The TimerProc gets called when the timer expires. It gets passed
-** the TimerClientData associated with the timer, and a timeval in case
+** the TimerClientData associated with the timer, and a iperf_time in case
** it wants to schedule another timer.
*/
-typedef void TimerProc( TimerClientData client_data, struct timeval* nowP );
+typedef void TimerProc( TimerClientData client_data, struct iperf_time* nowP );
/* The Timer struct. */
typedef struct TimerStruct
@@ -58,7 +59,7 @@ typedef struct TimerStruct
TimerClientData client_data;
int64_t usecs;
int periodic;
- struct timeval time;
+ struct iperf_time time;
struct TimerStruct* prev;
struct TimerStruct* next;
int hash;
@@ -66,22 +67,22 @@ typedef struct TimerStruct
/* Set up a timer, either periodic or one-shot. Returns (Timer*) 0 on errors. */
extern Timer* tmr_create(
- struct timeval* nowP, TimerProc* timer_proc, TimerClientData client_data,
+ struct iperf_time* nowP, TimerProc* timer_proc, TimerClientData client_data,
int64_t usecs, int periodic );
/* Returns a timeout indicating how long until the next timer triggers. You
** can just put the call to this routine right in your select(). Returns
** (struct timeval*) 0 if no timers are pending.
*/
-extern struct timeval* tmr_timeout( struct timeval* nowP ) /* __attribute__((hot)) */;
+extern struct timeval* tmr_timeout( struct iperf_time* nowP ) /* __attribute__((hot)) */;
/* Run the list of timers. Your main program needs to call this every so often,
** or as indicated by tmr_timeout().
*/
-extern void tmr_run( struct timeval* nowP ) /* __attribute__((hot)) */;
+extern void tmr_run( struct iperf_time* nowP ) /* __attribute__((hot)) */;
/* Reset the clock on a timer, to current time plus the original timeout. */
-extern void tmr_reset( struct timeval* nowP, Timer* timer );
+extern void tmr_reset( struct iperf_time* nowP, Timer* timer );
/* Deschedule a timer. Note that non-periodic timers are automatically
** descheduled when they run, so you don't have to call this on them.