1
1

Add portable time abstraction (#738). Fixes #253.

From author's notes (@ben-foxmore):

The current usage of gettimeofday causes issues for us when performing
tests shortly after restarting a system. In our setup, this occurs
often as we restart the system before each test to ensure reliable
results. We already maintain our own version of iperf for some subtle
changes, but this change feels like it might be useful to upstream.
(It's also a reasonable size change, so we'd prefer not maintain it
with each new version of iperf.)

It uses clock_gettime on systems that have it available, and falls
back to gettimeofday when it's not. These two options use different
structures for storing time - clock_gettime uses timespec, and
gettimeofday uses timeval. To provide abstraction to which one is
available, a separate iperf_time struct is defined to store time.

timespec has nanosecond accuracy, while timeval only has microseconds.
For the purposes of iperf, I don't think nanosecond accuracy is
neccesary, so iperf_time only uses microseconds, throwing away any
additional accuracy. Currently I have used the MONOTONIC clock, as I
think we only need a consistent time interval measure.
Этот коммит содержится в:
Bruce A. Mah 2018-09-28 11:24:12 -07:00
родитель 197d27ac76 64d1be0fcc
Коммит a68171340f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4984910A8CAAEE8A
17 изменённых файлов: 460 добавлений и 145 удалений

69
configure поставляемый
Просмотреть файл

@ -13111,6 +13111,75 @@ $as_echo "#define HAVE_SO_MAX_PACING_RATE 1" >>confdefs.h
fi 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" ac_config_files="$ac_config_files Makefile src/Makefile src/version.h examples/Makefile iperf3.spec"

Просмотреть файл

@ -189,5 +189,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.]) AC_DEFINE([HAVE_SO_MAX_PACING_RATE], [1], [Have SO_MAX_PACING_RATE sockopt.])
fi 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]) AC_OUTPUT([Makefile src/Makefile src/version.h examples/Makefile iperf3.spec])

Просмотреть файл

@ -31,7 +31,9 @@ libiperf_la_SOURCES = \
iperf_sctp.h \ iperf_sctp.h \
iperf_util.c \ iperf_util.c \
iperf_util.h \ iperf_util.h \
dscp.c \ iperf_time.c \
iperf_time.h \
dscp.c \
net.c \ net.c \
net.h \ net.h \
portable_endian.h \ portable_endian.h \

Просмотреть файл

@ -147,7 +147,8 @@ libiperf_la_LIBADD =
am_libiperf_la_OBJECTS = cjson.lo iperf_api.lo iperf_error.lo \ am_libiperf_la_OBJECTS = cjson.lo iperf_api.lo iperf_error.lo \
iperf_auth.lo iperf_client_api.lo iperf_locale.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_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) libiperf_la_OBJECTS = $(am_libiperf_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@) AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -164,8 +165,9 @@ am__iperf3_profile_SOURCES_DIST = main.c cjson.c cjson.h flowlabel.h \
iperf_auth.c iperf_client_api.c iperf_locale.c iperf_locale.h \ iperf_auth.c iperf_client_api.c iperf_locale.c iperf_locale.h \
iperf_server_api.c iperf_tcp.c iperf_tcp.h iperf_udp.c \ iperf_server_api.c iperf_tcp.c iperf_tcp.h iperf_udp.c \
iperf_udp.h iperf_sctp.c iperf_sctp.h iperf_util.c \ iperf_udp.h iperf_sctp.c iperf_sctp.h iperf_util.c \
iperf_util.h dscp.c net.c net.h portable_endian.h queue.h \ iperf_util.h iperf_time.c iperf_time.h dscp.c net.c net.h \
tcp_info.c timer.c timer.h units.c units.h version.h portable_endian.h queue.h tcp_info.c timer.c timer.h units.c \
units.h version.h
am__objects_1 = iperf3_profile-cjson.$(OBJEXT) \ am__objects_1 = iperf3_profile-cjson.$(OBJEXT) \
iperf3_profile-iperf_api.$(OBJEXT) \ iperf3_profile-iperf_api.$(OBJEXT) \
iperf3_profile-iperf_error.$(OBJEXT) \ iperf3_profile-iperf_error.$(OBJEXT) \
@ -177,6 +179,7 @@ am__objects_1 = iperf3_profile-cjson.$(OBJEXT) \
iperf3_profile-iperf_udp.$(OBJEXT) \ iperf3_profile-iperf_udp.$(OBJEXT) \
iperf3_profile-iperf_sctp.$(OBJEXT) \ iperf3_profile-iperf_sctp.$(OBJEXT) \
iperf3_profile-iperf_util.$(OBJEXT) \ iperf3_profile-iperf_util.$(OBJEXT) \
iperf3_profile-iperf_time.$(OBJEXT) \
iperf3_profile-dscp.$(OBJEXT) iperf3_profile-net.$(OBJEXT) \ iperf3_profile-dscp.$(OBJEXT) iperf3_profile-net.$(OBJEXT) \
iperf3_profile-tcp_info.$(OBJEXT) \ iperf3_profile-tcp_info.$(OBJEXT) \
iperf3_profile-timer.$(OBJEXT) iperf3_profile-units.$(OBJEXT) iperf3_profile-timer.$(OBJEXT) iperf3_profile-units.$(OBJEXT)
@ -239,6 +242,7 @@ am__depfiles_remade = ./$(DEPDIR)/cjson.Plo ./$(DEPDIR)/dscp.Plo \
./$(DEPDIR)/iperf3_profile-iperf_sctp.Po \ ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po \
./$(DEPDIR)/iperf3_profile-iperf_server_api.Po \ ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po \
./$(DEPDIR)/iperf3_profile-iperf_tcp.Po \ ./$(DEPDIR)/iperf3_profile-iperf_tcp.Po \
./$(DEPDIR)/iperf3_profile-iperf_time.Po \
./$(DEPDIR)/iperf3_profile-iperf_udp.Po \ ./$(DEPDIR)/iperf3_profile-iperf_udp.Po \
./$(DEPDIR)/iperf3_profile-iperf_util.Po \ ./$(DEPDIR)/iperf3_profile-iperf_util.Po \
./$(DEPDIR)/iperf3_profile-main.Po \ ./$(DEPDIR)/iperf3_profile-main.Po \
@ -249,12 +253,12 @@ am__depfiles_remade = ./$(DEPDIR)/cjson.Plo ./$(DEPDIR)/dscp.Plo \
./$(DEPDIR)/iperf_auth.Plo ./$(DEPDIR)/iperf_client_api.Plo \ ./$(DEPDIR)/iperf_auth.Plo ./$(DEPDIR)/iperf_client_api.Plo \
./$(DEPDIR)/iperf_error.Plo ./$(DEPDIR)/iperf_locale.Plo \ ./$(DEPDIR)/iperf_error.Plo ./$(DEPDIR)/iperf_locale.Plo \
./$(DEPDIR)/iperf_sctp.Plo ./$(DEPDIR)/iperf_server_api.Plo \ ./$(DEPDIR)/iperf_sctp.Plo ./$(DEPDIR)/iperf_server_api.Plo \
./$(DEPDIR)/iperf_tcp.Plo ./$(DEPDIR)/iperf_udp.Plo \ ./$(DEPDIR)/iperf_tcp.Plo ./$(DEPDIR)/iperf_time.Plo \
./$(DEPDIR)/iperf_util.Plo ./$(DEPDIR)/net.Plo \ ./$(DEPDIR)/iperf_udp.Plo ./$(DEPDIR)/iperf_util.Plo \
./$(DEPDIR)/t_api-t_api.Po ./$(DEPDIR)/t_timer-t_timer.Po \ ./$(DEPDIR)/net.Plo ./$(DEPDIR)/t_api-t_api.Po \
./$(DEPDIR)/t_units-t_units.Po ./$(DEPDIR)/t_uuid-t_uuid.Po \ ./$(DEPDIR)/t_timer-t_timer.Po ./$(DEPDIR)/t_units-t_units.Po \
./$(DEPDIR)/tcp_info.Plo ./$(DEPDIR)/timer.Plo \ ./$(DEPDIR)/t_uuid-t_uuid.Po ./$(DEPDIR)/tcp_info.Plo \
./$(DEPDIR)/units.Plo ./$(DEPDIR)/timer.Plo ./$(DEPDIR)/units.Plo
am__mv = mv -f am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@ -639,7 +643,9 @@ libiperf_la_SOURCES = \
iperf_sctp.h \ iperf_sctp.h \
iperf_util.c \ iperf_util.c \
iperf_util.h \ iperf_util.h \
dscp.c \ iperf_time.c \
iperf_time.h \
dscp.c \
net.c \ net.c \
net.h \ net.h \
portable_endian.h \ portable_endian.h \
@ -877,6 +883,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_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_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_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_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-iperf_util.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-main.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-main.Po@am__quote@ # am--include-marker
@ -892,6 +899,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_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_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_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_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)/iperf_util.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Plo@am__quote@ # am--include-marker
@ -1112,6 +1120,20 @@ iperf3_profile-iperf_util.obj: iperf_util.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @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_util.obj `if test -f 'iperf_util.c'; then $(CYGPATH_W) 'iperf_util.c'; else $(CYGPATH_W) '$(srcdir)/iperf_util.c'; fi` @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 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_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 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/iperf3_profile-dscp.Tpo $(DEPDIR)/iperf3_profile-dscp.Po
@ -1683,6 +1705,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po -rm -f ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po -rm -f ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_tcp.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_udp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_util.Po -rm -f ./$(DEPDIR)/iperf3_profile-iperf_util.Po
-rm -f ./$(DEPDIR)/iperf3_profile-main.Po -rm -f ./$(DEPDIR)/iperf3_profile-main.Po
@ -1698,6 +1721,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/iperf_sctp.Plo -rm -f ./$(DEPDIR)/iperf_sctp.Plo
-rm -f ./$(DEPDIR)/iperf_server_api.Plo -rm -f ./$(DEPDIR)/iperf_server_api.Plo
-rm -f ./$(DEPDIR)/iperf_tcp.Plo -rm -f ./$(DEPDIR)/iperf_tcp.Plo
-rm -f ./$(DEPDIR)/iperf_time.Plo
-rm -f ./$(DEPDIR)/iperf_udp.Plo -rm -f ./$(DEPDIR)/iperf_udp.Plo
-rm -f ./$(DEPDIR)/iperf_util.Plo -rm -f ./$(DEPDIR)/iperf_util.Plo
-rm -f ./$(DEPDIR)/net.Plo -rm -f ./$(DEPDIR)/net.Plo
@ -1766,6 +1790,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po -rm -f ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po -rm -f ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_tcp.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_udp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_util.Po -rm -f ./$(DEPDIR)/iperf3_profile-iperf_util.Po
-rm -f ./$(DEPDIR)/iperf3_profile-main.Po -rm -f ./$(DEPDIR)/iperf3_profile-main.Po
@ -1781,6 +1806,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/iperf_sctp.Plo -rm -f ./$(DEPDIR)/iperf_sctp.Plo
-rm -f ./$(DEPDIR)/iperf_server_api.Plo -rm -f ./$(DEPDIR)/iperf_server_api.Plo
-rm -f ./$(DEPDIR)/iperf_tcp.Plo -rm -f ./$(DEPDIR)/iperf_tcp.Plo
-rm -f ./$(DEPDIR)/iperf_time.Plo
-rm -f ./$(DEPDIR)/iperf_udp.Plo -rm -f ./$(DEPDIR)/iperf_udp.Plo
-rm -f ./$(DEPDIR)/iperf_util.Plo -rm -f ./$(DEPDIR)/iperf_util.Plo
-rm -f ./$(DEPDIR)/net.Plo -rm -f ./$(DEPDIR)/net.Plo

Просмотреть файл

@ -61,6 +61,7 @@
#include "timer.h" #include "timer.h"
#include "queue.h" #include "queue.h"
#include "cjson.h" #include "cjson.h"
#include "iperf_time.h"
#if defined(HAVE_SSL) #if defined(HAVE_SSL)
#include <openssl/bio.h> #include <openssl/bio.h>
@ -72,8 +73,8 @@ typedef uint64_t iperf_size_t;
struct iperf_interval_results struct iperf_interval_results
{ {
iperf_size_t bytes_transferred; /* bytes transfered in this interval */ iperf_size_t bytes_transferred; /* bytes transfered in this interval */
struct timeval interval_start_time; struct iperf_time interval_start_time;
struct timeval interval_end_time; struct iperf_time interval_end_time;
float interval_duration; float interval_duration;
/* for UDP */ /* for UDP */
@ -119,9 +120,9 @@ struct iperf_stream_result
int stream_sum_rtt; int stream_sum_rtt;
int stream_count_rtt; int stream_count_rtt;
int stream_max_snd_cwnd; int stream_max_snd_cwnd;
struct timeval start_time; struct iperf_time start_time;
struct timeval end_time; struct iperf_time end_time;
struct timeval start_time_fixed; struct iperf_time start_time_fixed;
double sender_time; double sender_time;
double receiver_time; double receiver_time;
TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results; TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results;

Просмотреть файл

@ -1304,14 +1304,16 @@ iperf_set_send_state(struct iperf_test *test, signed char state)
} }
void 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; double seconds;
uint64_t bits_per_second; uint64_t bits_per_second;
if (sp->test->done) if (sp->test->done)
return; 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; bits_per_second = sp->result->bytes_sent * 8 / seconds;
if (bits_per_second < sp->test->settings->rate) { if (bits_per_second < sp->test->settings->rate) {
sp->green_light = 1; sp->green_light = 1;
@ -1327,7 +1329,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
{ {
register int multisend, r, streams_active; register int multisend, r, streams_active;
register struct iperf_stream *sp; register struct iperf_stream *sp;
struct timeval now; struct iperf_time now;
/* Can we do multisend mode? */ /* Can we do multisend mode? */
if (test->settings->burst != 0) if (test->settings->burst != 0)
@ -1339,7 +1341,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
for (; multisend > 0; --multisend) { for (; multisend > 0; --multisend) {
if (test->settings->rate != 0 && test->settings->burst == 0) if (test->settings->rate != 0 && test->settings->burst == 0)
gettimeofday(&now, NULL); iperf_time_now(&now);
streams_active = 0; streams_active = 0;
SLIST_FOREACH(sp, &test->streams, streams) { SLIST_FOREACH(sp, &test->streams, streams) {
if ((sp->green_light && if ((sp->green_light &&
@ -1365,7 +1367,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
break; break;
} }
if (test->settings->burst != 0) { if (test->settings->burst != 0) {
gettimeofday(&now, NULL); iperf_time_now(&now);
SLIST_FOREACH(sp, &test->streams, streams) SLIST_FOREACH(sp, &test->streams, streams)
iperf_check_throttle(sp, &now); iperf_check_throttle(sp, &now);
} }
@ -1401,7 +1403,7 @@ iperf_recv(struct iperf_test *test, fd_set *read_setP)
int int
iperf_init_test(struct iperf_test *test) iperf_init_test(struct iperf_test *test)
{ {
struct timeval now; struct iperf_time now;
struct iperf_stream *sp; struct iperf_stream *sp;
if (test->protocol->init) { if (test->protocol->init) {
@ -1410,7 +1412,7 @@ iperf_init_test(struct iperf_test *test)
} }
/* Init each stream. */ /* Init each stream. */
if (gettimeofday(&now, NULL) < 0) { if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST; i_errno = IEINITTEST;
return -1; return -1;
} }
@ -1425,7 +1427,7 @@ iperf_init_test(struct iperf_test *test)
} }
static void 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; struct iperf_stream *sp = client_data.p;
@ -1439,11 +1441,11 @@ send_timer_proc(TimerClientData client_data, struct timeval *nowP)
int int
iperf_create_send_timers(struct iperf_test * test) iperf_create_send_timers(struct iperf_test * test)
{ {
struct timeval now; struct iperf_time now;
struct iperf_stream *sp; struct iperf_stream *sp;
TimerClientData cd; TimerClientData cd;
if (gettimeofday(&now, NULL) < 0) { if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST; i_errno = IEINITTEST;
return -1; return -1;
} }
@ -1451,7 +1453,7 @@ iperf_create_send_timers(struct iperf_test * test)
sp->green_light = 1; sp->green_light = 1;
if (test->settings->rate != 0) { if (test->settings->rate != 0) {
cd.p = sp; 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) { if (sp->send_timer == NULL) {
i_errno = IEINITTEST; i_errno = IEINITTEST;
return -1; return -1;
@ -1749,6 +1751,7 @@ send_results(struct iperf_test *test)
int sender_has_retransmits; int sender_has_retransmits;
iperf_size_t bytes_transferred; iperf_size_t bytes_transferred;
int retransmits; int retransmits;
struct iperf_time temp_time;
double start_time, end_time; double start_time, end_time;
j = cJSON_CreateObject(); j = cJSON_CreateObject();
@ -1818,8 +1821,10 @@ send_results(struct iperf_test *test)
cJSON_AddNumberToObject(j_stream, "errors", sp->cnt_error); cJSON_AddNumberToObject(j_stream, "errors", sp->cnt_error);
cJSON_AddNumberToObject(j_stream, "packets", sp->packet_count); cJSON_AddNumberToObject(j_stream, "packets", sp->packet_count);
start_time = timeval_diff(&sp->result->start_time, &sp->result->start_time); iperf_time_diff(&sp->result->start_time, &sp->result->start_time, &temp_time);
end_time = timeval_diff(&sp->result->start_time, &sp->result->end_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, "start_time", start_time);
cJSON_AddNumberToObject(j_stream, "end_time", end_time); cJSON_AddNumberToObject(j_stream, "end_time", end_time);
@ -2490,13 +2495,13 @@ iperf_reset_test(struct iperf_test *test)
void void
iperf_reset_stats(struct iperf_test *test) iperf_reset_stats(struct iperf_test *test)
{ {
struct timeval now; struct iperf_time now;
struct iperf_stream *sp; struct iperf_stream *sp;
struct iperf_stream_result *rp; struct iperf_stream_result *rp;
test->bytes_sent = 0; test->bytes_sent = 0;
test->blocks_sent = 0; test->blocks_sent = 0;
gettimeofday(&now, NULL); iperf_time_now(&now);
SLIST_FOREACH(sp, &test->streams, streams) { SLIST_FOREACH(sp, &test->streams, streams) {
sp->omitted_packet_count = sp->packet_count; sp->omitted_packet_count = sp->packet_count;
sp->omitted_cnt_error = sp->cnt_error; sp->omitted_cnt_error = sp->cnt_error;
@ -2529,6 +2534,7 @@ iperf_stats_callback(struct iperf_test *test)
struct iperf_stream *sp; struct iperf_stream *sp;
struct iperf_stream_result *rp = NULL; struct iperf_stream_result *rp = NULL;
struct iperf_interval_results *irp, temp; struct iperf_interval_results *irp, temp;
struct iperf_time temp_time;
temp.omitted = test->omitting; temp.omitted = test->omitting;
SLIST_FOREACH(sp, &test->streams, streams) { SLIST_FOREACH(sp, &test->streams, streams) {
@ -2539,14 +2545,14 @@ iperf_stats_callback(struct iperf_test *test)
irp = TAILQ_LAST(&rp->interval_results, irlisthead); irp = TAILQ_LAST(&rp->interval_results, irlisthead);
/* result->end_time contains timestamp of previous interval */ /* result->end_time contains timestamp of previous interval */
if ( irp != NULL ) /* not the 1st 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 */ 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 */ /* now save time of end of this interval */
gettimeofday(&rp->end_time, NULL); iperf_time_now(&rp->end_time);
memcpy(&temp.interval_end_time, &rp->end_time, sizeof(struct timeval)); memcpy(&temp.interval_end_time, &rp->end_time, sizeof(struct iperf_time));
temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time); iperf_time_diff(&temp.interval_start_time, &temp.interval_end_time, &temp_time);
//temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time); temp.interval_duration = iperf_time_in_secs(&temp_time);
if (test->protocol->id == Ptcp) { if (test->protocol->id == Ptcp) {
if ( has_tcpinfo()) { if ( has_tcpinfo()) {
save_tcpinfo(sp, &temp); save_tcpinfo(sp, &temp);
@ -2613,6 +2619,7 @@ iperf_print_intermediate(struct iperf_test *test)
double bandwidth; double bandwidth;
int retransmits = 0; int retransmits = 0;
double start_time, end_time; double start_time, end_time;
struct iperf_time temp_time;
cJSON *json_interval; cJSON *json_interval;
cJSON *json_interval_streams; cJSON *json_interval_streams;
int total_packets = 0, lost_packets = 0; int total_packets = 0, lost_packets = 0;
@ -2635,8 +2642,8 @@ iperf_print_intermediate(struct iperf_test *test)
SLIST_FOREACH(sp, &test->streams, streams) { SLIST_FOREACH(sp, &test->streams, streams) {
irp = TAILQ_LAST(&sp->result->interval_results, irlisthead); irp = TAILQ_LAST(&sp->result->interval_results, irlisthead);
if (irp) { if (irp) {
double interval_len = timeval_diff(&irp->interval_start_time, iperf_time_diff(&irp->interval_start_time, &irp->interval_end_time, &temp_time);
&irp->interval_end_time); double interval_len = iperf_time_in_secs(&temp_time);
if (test->debug) { if (test->debug) {
printf("interval_len %f bytes_transferred %" PRIu64 "\n", interval_len, irp->bytes_transferred); printf("interval_len %f bytes_transferred %" PRIu64 "\n", interval_len, irp->bytes_transferred);
} }
@ -2701,14 +2708,16 @@ iperf_print_intermediate(struct iperf_test *test)
sp = SLIST_FIRST(&test->streams); /* reset back to 1st stream */ sp = SLIST_FIRST(&test->streams); /* reset back to 1st stream */
/* Only do this of course if there was a first stream */ /* Only do this of course if there was a first stream */
if (sp) { 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'); unit_snprintf(ubuf, UNIT_LEN, (double) bytes, 'A');
bandwidth = (double) bytes / (double) irp->interval_duration; bandwidth = (double) bytes / (double) irp->interval_duration;
unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format); unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
start_time = timeval_diff(&sp->result->start_time,&irp->interval_start_time); iperf_time_diff(&sp->result->start_time,&irp->interval_start_time, &temp_time);
end_time = timeval_diff(&sp->result->start_time,&irp->interval_end_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->protocol->id == Ptcp || test->protocol->id == Psctp) {
if (test->sender_has_retransmits == 1) { if (test->sender_has_retransmits == 1) {
/* Interval sum, TCP with retransmits. */ /* Interval sum, TCP with retransmits. */
@ -2770,6 +2779,7 @@ iperf_print_results(struct iperf_test *test)
iperf_size_t bytes_received, total_received = 0; iperf_size_t bytes_received, total_received = 0;
double start_time, end_time = 0.0, avg_jitter = 0.0, lost_percent = 0.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; double sender_time = 0.0, receiver_time = 0.0;
struct iperf_time temp_time;
double bandwidth; double bandwidth;
/* print final summary for all intervals */ /* print final summary for all intervals */
@ -2807,7 +2817,8 @@ iperf_print_results(struct iperf_test *test)
* basically emulating what iperf 3.1 did. * basically emulating what iperf 3.1 did.
*/ */
if (sp) { 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) { if (test->sender) {
sp->result->sender_time = end_time; sp->result->sender_time = end_time;
if (sp->result->receiver_time == 0.0) { if (sp->result->receiver_time == 0.0) {
@ -3202,6 +3213,7 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
char nbuf[UNIT_LEN]; char nbuf[UNIT_LEN];
char cbuf[UNIT_LEN]; char cbuf[UNIT_LEN];
double st = 0., et = 0.; double st = 0., et = 0.;
struct iperf_time temp_time;
struct iperf_interval_results *irp = NULL; struct iperf_interval_results *irp = NULL;
double bandwidth, lost_percent; double bandwidth, lost_percent;
@ -3217,7 +3229,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 if there's more than one stream, print the separator;
** else nothing. ** 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->protocol->id == Ptcp || test->protocol->id == Psctp) {
if (test->sender_has_retransmits == 1) if (test->sender_has_retransmits == 1)
iperf_printf(test, "%s", report_bw_retrans_cwnd_header); iperf_printf(test, "%s", report_bw_retrans_cwnd_header);
@ -3243,8 +3255,10 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
} }
unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format); unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
st = timeval_diff(&sp->result->start_time, &irp->interval_start_time); iperf_time_diff(&sp->result->start_time, &irp->interval_start_time, &temp_time);
et = timeval_diff(&sp->result->start_time, &irp->interval_end_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->protocol->id == Ptcp || test->protocol->id == Psctp) {
if (test->sender_has_retransmits == 1) { if (test->sender_has_retransmits == 1) {

Просмотреть файл

@ -42,6 +42,7 @@ struct iperf_test;
struct iperf_stream_result; struct iperf_stream_result;
struct iperf_interval_results; struct iperf_interval_results;
struct iperf_stream; struct iperf_stream;
struct iperf_time;
/* default settings */ /* default settings */
#define Ptcp SOCK_STREAM #define Ptcp SOCK_STREAM
@ -247,7 +248,7 @@ void print_tcpinfo(struct iperf_test *test);
void build_tcpinfo_message(struct iperf_interval_results *r, char *message); void build_tcpinfo_message(struct iperf_interval_results *r, char *message);
int iperf_set_send_state(struct iperf_test *test, signed char state); 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_send(struct iperf_test *, fd_set *) /* __attribute__((hot)) */;
int iperf_recv(struct iperf_test *, fd_set *); int iperf_recv(struct iperf_test *, fd_set *);
void iperf_catch_sigend(void (*handler)(int)); void iperf_catch_sigend(void (*handler)(int));

Просмотреть файл

@ -41,6 +41,7 @@
#include "iperf_api.h" #include "iperf_api.h"
#include "iperf_util.h" #include "iperf_util.h"
#include "iperf_locale.h" #include "iperf_locale.h"
#include "iperf_time.h"
#include "net.h" #include "net.h"
#include "timer.h" #include "timer.h"
@ -116,7 +117,7 @@ iperf_create_streams(struct iperf_test *test)
} }
static void 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; struct iperf_test *test = client_data.p;
@ -125,7 +126,7 @@ test_timer_proc(TimerClientData client_data, struct timeval *nowP)
} }
static void 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; struct iperf_test *test = client_data.p;
@ -136,7 +137,7 @@ client_stats_timer_proc(TimerClientData client_data, struct timeval *nowP)
} }
static void 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; struct iperf_test *test = client_data.p;
@ -149,10 +150,10 @@ client_reporter_timer_proc(TimerClientData client_data, struct timeval *nowP)
static int static int
create_client_timers(struct iperf_test * test) create_client_timers(struct iperf_test * test)
{ {
struct timeval now; struct iperf_time now;
TimerClientData cd; TimerClientData cd;
if (gettimeofday(&now, NULL) < 0) { if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST; i_errno = IEINITTEST;
return -1; return -1;
} }
@ -184,7 +185,7 @@ create_client_timers(struct iperf_test * test)
} }
static void 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; struct iperf_test *test = client_data.p;
@ -204,14 +205,14 @@ client_omit_timer_proc(TimerClientData client_data, struct timeval *nowP)
static int static int
create_client_omit_timer(struct iperf_test * test) create_client_omit_timer(struct iperf_test * test)
{ {
struct timeval now; struct iperf_time now;
TimerClientData cd; TimerClientData cd;
if (test->omit == 0) { if (test->omit == 0) {
test->omit_timer = NULL; test->omit_timer = NULL;
test->omitting = 0; test->omitting = 0;
} else { } else {
if (gettimeofday(&now, NULL) < 0) { if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST; i_errno = IEINITTEST;
return -1; return -1;
} }
@ -442,7 +443,7 @@ iperf_run_client(struct iperf_test * test)
int startup; int startup;
int result = 0; int result = 0;
fd_set read_set, write_set; fd_set read_set, write_set;
struct timeval now; struct iperf_time now;
struct timeval* timeout = NULL; struct timeval* timeout = NULL;
struct iperf_stream *sp; struct iperf_stream *sp;
@ -475,7 +476,7 @@ iperf_run_client(struct iperf_test * test)
while (test->state != IPERF_DONE) { while (test->state != IPERF_DONE) {
memcpy(&read_set, &test->read_set, sizeof(fd_set)); memcpy(&read_set, &test->read_set, sizeof(fd_set));
memcpy(&write_set, &test->write_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); timeout = tmr_timeout(&now);
result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout); result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout);
if (result < 0 && errno != EINTR) { if (result < 0 && errno != EINTR) {
@ -516,7 +517,7 @@ iperf_run_client(struct iperf_test * test)
} }
/* Run the timers. */ /* Run the timers. */
(void) gettimeofday(&now, NULL); iperf_time_now(&now);
tmr_run(&now); tmr_run(&now);
/* Is the test done yet? */ /* Is the test done yet? */

Просмотреть файл

@ -1,5 +1,8 @@
/* src/iperf_config.h.in. Generated from configure.ac by autoheader. */ /* 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. */ /* Define to 1 if you have the `cpuset_setaffinity' function. */
#undef HAVE_CPUSET_SETAFFINITY #undef HAVE_CPUSET_SETAFFINITY

Просмотреть файл

@ -54,6 +54,7 @@
#include "iperf_tcp.h" #include "iperf_tcp.h"
#include "iperf_util.h" #include "iperf_util.h"
#include "timer.h" #include "timer.h"
#include "iperf_time.h"
#include "net.h" #include "net.h"
#include "units.h" #include "units.h"
#include "iperf_util.h" #include "iperf_util.h"
@ -223,7 +224,7 @@ iperf_handle_message_server(struct iperf_test *test)
} }
static void 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_test *test = client_data.p;
struct iperf_stream *sp; struct iperf_stream *sp;
@ -243,7 +244,7 @@ server_timer_proc(TimerClientData client_data, struct timeval *nowP)
} }
static void 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; struct iperf_test *test = client_data.p;
@ -254,7 +255,7 @@ server_stats_timer_proc(TimerClientData client_data, struct timeval *nowP)
} }
static void 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; struct iperf_test *test = client_data.p;
@ -267,10 +268,10 @@ server_reporter_timer_proc(TimerClientData client_data, struct timeval *nowP)
static int static int
create_server_timers(struct iperf_test * test) create_server_timers(struct iperf_test * test)
{ {
struct timeval now; struct iperf_time now;
TimerClientData cd; TimerClientData cd;
if (gettimeofday(&now, NULL) < 0) { if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST; i_errno = IEINITTEST;
return -1; return -1;
} }
@ -304,7 +305,7 @@ create_server_timers(struct iperf_test * test)
} }
static void 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; struct iperf_test *test = client_data.p;
@ -324,14 +325,14 @@ server_omit_timer_proc(TimerClientData client_data, struct timeval *nowP)
static int static int
create_server_omit_timer(struct iperf_test * test) create_server_omit_timer(struct iperf_test * test)
{ {
struct timeval now; struct iperf_time now;
TimerClientData cd; TimerClientData cd;
if (test->omit == 0) { if (test->omit == 0) {
test->omit_timer = NULL; test->omit_timer = NULL;
test->omitting = 0; test->omitting = 0;
} else { } else {
if (gettimeofday(&now, NULL) < 0) { if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST; i_errno = IEINITTEST;
return -1; return -1;
} }
@ -391,7 +392,7 @@ iperf_run_server(struct iperf_test *test)
#endif /* HAVE_TCP_CONGESTION */ #endif /* HAVE_TCP_CONGESTION */
fd_set read_set, write_set; fd_set read_set, write_set;
struct iperf_stream *sp; struct iperf_stream *sp;
struct timeval now; struct iperf_time now;
struct timeval* timeout; struct timeval* timeout;
if (test->affinity != -1) 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(&read_set, &test->read_set, sizeof(fd_set));
memcpy(&write_set, &test->write_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); timeout = tmr_timeout(&now);
result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout); result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout);
if (result < 0 && errno != EINTR) { if (result < 0 && errno != EINTR) {
@ -606,7 +607,7 @@ iperf_run_server(struct iperf_test *test)
if (result == 0 || if (result == 0 ||
(timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)) { (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)) {
/* Run the timers. */ /* Run the timers. */
(void) gettimeofday(&now, NULL); iperf_time_now(&now);
tmr_run(&now); tmr_run(&now);
} }
} }

156
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;
}

49
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

Просмотреть файл

@ -66,7 +66,7 @@ iperf_udp_recv(struct iperf_stream *sp)
int r; int r;
int size = sp->settings->blksize; int size = sp->settings->blksize;
double transit = 0, d = 0; 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); r = Nread(sp->socket, sp->buffer, size, Pudp);
@ -90,8 +90,8 @@ iperf_udp_recv(struct iperf_stream *sp)
sec = ntohl(sec); sec = ntohl(sec);
usec = ntohl(usec); usec = ntohl(usec);
pcount = be64toh(pcount); pcount = be64toh(pcount);
sent_time.tv_sec = sec; sent_time.secs = sec;
sent_time.tv_usec = usec; sent_time.usecs = usec;
} }
else { else {
uint32_t pc; uint32_t pc;
@ -101,8 +101,8 @@ iperf_udp_recv(struct iperf_stream *sp)
sec = ntohl(sec); sec = ntohl(sec);
usec = ntohl(usec); usec = ntohl(usec);
pcount = ntohl(pc); pcount = ntohl(pc);
sent_time.tv_sec = sec; sent_time.secs = sec;
sent_time.tv_usec = usec; sent_time.usecs = usec;
} }
if (sp->test->debug) if (sp->test->debug)
@ -163,9 +163,10 @@ iperf_udp_recv(struct iperf_stream *sp)
* computation does not require knowing the round-trip * computation does not require knowing the round-trip
* time. * 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; d = transit - sp->prev_transit;
if (d < 0) if (d < 0)
d = -d; d = -d;
@ -190,9 +191,9 @@ iperf_udp_send(struct iperf_stream *sp)
{ {
int r; int r;
int size = sp->settings->blksize; int size = sp->settings->blksize;
struct timeval before; struct iperf_time before;
gettimeofday(&before, 0); iperf_time_now(&before);
++sp->packet_count; ++sp->packet_count;
@ -201,8 +202,8 @@ iperf_udp_send(struct iperf_stream *sp)
uint32_t sec, usec; uint32_t sec, usec;
uint64_t pcount; uint64_t pcount;
sec = htonl(before.tv_sec); sec = htonl(before.secs);
usec = htonl(before.tv_usec); usec = htonl(before.usecs);
pcount = htobe64(sp->packet_count); pcount = htobe64(sp->packet_count);
memcpy(sp->buffer, &sec, sizeof(sec)); memcpy(sp->buffer, &sec, sizeof(sec));
@ -214,8 +215,8 @@ iperf_udp_send(struct iperf_stream *sp)
uint32_t sec, usec, pcount; uint32_t sec, usec, pcount;
sec = htonl(before.tv_sec); sec = htonl(before.secs);
usec = htonl(before.tv_usec); usec = htonl(before.usecs);
pcount = htonl(sp->packet_count); pcount = htonl(sp->packet_count);
memcpy(sp->buffer, &sec, sizeof(sec)); memcpy(sp->buffer, &sec, sizeof(sec));

Просмотреть файл

@ -189,10 +189,10 @@ timeval_diff(struct timeval * tv0, struct timeval * tv1)
void void
cpu_util(double pcpu[3]) cpu_util(double pcpu[3])
{ {
static struct timeval last; static struct iperf_time last;
static clock_t clast; static clock_t clast;
static struct rusage rlast; static struct rusage rlast;
struct timeval temp; struct iperf_time now, temp_time;
clock_t ctemp; clock_t ctemp;
struct rusage rtemp; struct rusage rtemp;
double timediff; double timediff;
@ -200,18 +200,19 @@ cpu_util(double pcpu[3])
double systemdiff; double systemdiff;
if (pcpu == NULL) { if (pcpu == NULL) {
gettimeofday(&last, NULL); iperf_time_now(&last);
clast = clock(); clast = clock();
getrusage(RUSAGE_SELF, &rlast); getrusage(RUSAGE_SELF, &rlast);
return; return;
} }
gettimeofday(&temp, NULL); iperf_time_now(&now);
ctemp = clock(); ctemp = clock();
getrusage(RUSAGE_SELF, &rtemp); getrusage(RUSAGE_SELF, &rtemp);
timediff = ((temp.tv_sec * 1000000.0 + temp.tv_usec) - iperf_time_diff(&now, &last, &temp_time);
(last.tv_sec * 1000000.0 + last.tv_usec)); timediff = iperf_time_in_secs(&temp_time);
userdiff = ((rtemp.ru_utime.tv_sec * 1000000.0 + rtemp.ru_utime.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)); (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) - systemdiff = ((rtemp.ru_stime.tv_sec * 1000000.0 + rtemp.ru_stime.tv_usec) -

Просмотреть файл

@ -35,13 +35,14 @@
#include <sys/time.h> #include <sys/time.h>
#include "timer.h" #include "timer.h"
#include "iperf_time.h"
static int flag; static int flag;
static void static void
timer_proc( TimerClientData client_data, struct timeval* nowP ) timer_proc( TimerClientData client_data, struct iperf_time* nowP )
{ {
flag = 1; flag = 1;
} }
@ -53,7 +54,7 @@ main(int argc, char **argv)
Timer *tp; Timer *tp;
flag = 0; flag = 0;
tp = tmr_create((struct timeval*) 0, timer_proc, JunkClientData, 3000000, 0); tp = tmr_create(NULL, timer_proc, JunkClientData, 3000000, 0);
if (!tp) if (!tp)
{ {
printf("failed to create timer\n"); printf("failed to create timer\n");
@ -62,7 +63,7 @@ main(int argc, char **argv)
sleep(2); sleep(2);
tmr_run((struct timeval*) 0); tmr_run(NULL);
if (flag) if (flag)
{ {
printf("timer should not have expired\n"); printf("timer should not have expired\n");
@ -70,7 +71,7 @@ main(int argc, char **argv)
} }
sleep(1); sleep(1);
tmr_run((struct timeval*) 0); tmr_run(NULL);
if (!flag) if (!flag)
{ {
printf("timer should have expired\n"); printf("timer should have expired\n");

Просмотреть файл

@ -31,7 +31,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "timer.h" #include "timer.h"
#include "iperf_time.h"
static Timer* timers = NULL; static Timer* timers = NULL;
static Timer* free_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 /* 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 ** current time get passed a pointer to a struct iperf_time. If it's non-NULL
** it gets used, otherwise we do our own gettimeofday() to fill it in. ** it gets used, otherwise we do our own iperf_time_now() to fill it in.
** This lets the caller avoid extraneous gettimeofday()s when efficiency ** 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 ** is needed, and not bother with the extra code when efficiency doesn't
** matter too much. ** matter too much.
*/ */
static void static void
getnow( struct timeval* nowP, struct timeval* nowP2 ) getnow( struct iperf_time* nowP, struct iperf_time* nowP2 )
{ {
if ( nowP != NULL ) if ( nowP != NULL )
*nowP2 = *nowP; *nowP2 = *nowP;
else else
(void) gettimeofday( nowP2, NULL ); iperf_time_now(nowP2);
} }
@ -68,9 +68,7 @@ list_add( Timer* t )
timers = t; timers = t;
t->prev = t->next = NULL; t->prev = t->next = NULL;
} else { } else {
if ( t->time.tv_sec < timers->time.tv_sec || if (iperf_time_compare(&t->time, &timers->time) < 0) {
( t->time.tv_sec == timers->time.tv_sec &&
t->time.tv_usec < timers->time.tv_usec ) ) {
/* The new timer goes at the head of the list. */ /* The new timer goes at the head of the list. */
t->prev = NULL; t->prev = NULL;
t->next = timers; t->next = timers;
@ -80,9 +78,7 @@ list_add( Timer* t )
/* Walk the list to find the insertion point. */ /* Walk the list to find the insertion point. */
for ( t2prev = timers, t2 = timers->next; t2 != NULL; for ( t2prev = timers, t2 = timers->next; t2 != NULL;
t2prev = t2, t2 = t2->next ) { t2prev = t2, t2 = t2->next ) {
if ( t->time.tv_sec < t2->time.tv_sec || if (iperf_time_compare(&t->time, &t2->time) < 0) {
( t->time.tv_sec == t2->time.tv_sec &&
t->time.tv_usec < t2->time.tv_usec ) ) {
/* Found it. */ /* Found it. */
t2prev->next = t; t2prev->next = t;
t->prev = t2prev; 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* Timer*
tmr_create( 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 ) int64_t usecs, int periodic )
{ {
struct timeval now; struct iperf_time now;
Timer* t; Timer* t;
getnow( nowP, &now ); getnow( nowP, &now );
@ -158,7 +142,7 @@ tmr_create(
t->usecs = usecs; t->usecs = usecs;
t->periodic = periodic; t->periodic = periodic;
t->time = now; t->time = now;
add_usecs( &t->time, usecs ); iperf_time_add_usecs(&t->time, usecs);
/* Add the new timer to the active list. */ /* Add the new timer to the active list. */
list_add( t ); list_add( t );
@ -167,20 +151,22 @@ tmr_create(
struct timeval* struct timeval*
tmr_timeout( struct timeval* nowP ) tmr_timeout( struct iperf_time* nowP )
{ {
struct timeval now; struct iperf_time now, diff;
int64_t usecs; int64_t usecs;
int past;
static struct timeval timeout; static struct timeval timeout;
getnow( nowP, &now ); getnow( nowP, &now );
/* Since the list is sorted, we only need to look at the first timer. */ /* Since the list is sorted, we only need to look at the first timer. */
if ( timers == NULL ) if ( timers == NULL )
return NULL; return NULL;
usecs = ( timers->time.tv_sec - now.tv_sec ) * 1000000LL + past = iperf_time_diff(&timers->time, &now, &diff);
( timers->time.tv_usec - now.tv_usec ); if (past)
if ( usecs <= 0 ) usecs = 0;
usecs = 0; else
usecs = iperf_time_in_usecs(&diff);
timeout.tv_sec = usecs / 1000000LL; timeout.tv_sec = usecs / 1000000LL;
timeout.tv_usec = usecs % 1000000LL; timeout.tv_usec = usecs % 1000000LL;
return &timeout; return &timeout;
@ -188,9 +174,9 @@ tmr_timeout( struct timeval* nowP )
void void
tmr_run( struct timeval* nowP ) tmr_run( struct iperf_time* nowP )
{ {
struct timeval now; struct iperf_time now;
Timer* t; Timer* t;
Timer* next; Timer* next;
@ -200,14 +186,12 @@ tmr_run( struct timeval* nowP )
/* Since the list is sorted, as soon as we find a timer /* Since the list is sorted, as soon as we find a timer
** that isn't ready yet, we are done. ** that isn't ready yet, we are done.
*/ */
if ( t->time.tv_sec > now.tv_sec || if (iperf_time_compare(&t->time, &now) > 0)
( t->time.tv_sec == now.tv_sec &&
t->time.tv_usec > now.tv_usec ) )
break; break;
(t->timer_proc)( t->client_data, &now ); (t->timer_proc)( t->client_data, &now );
if ( t->periodic ) { if ( t->periodic ) {
/* Reschedule. */ /* Reschedule. */
add_usecs( &t->time, t->usecs ); iperf_time_add_usecs(&t->time, t->usecs);
list_resort( t ); list_resort( t );
} else } else
tmr_cancel( t ); tmr_cancel( t );
@ -216,13 +200,13 @@ tmr_run( struct timeval* nowP )
void 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 ); getnow( nowP, &now );
t->time = now; t->time = now;
add_usecs( &t->time, t->usecs ); iperf_time_add_usecs( &t->time, t->usecs );
list_resort( t ); list_resort( t );
} }

Просмотреть файл

@ -30,7 +30,8 @@
#ifndef __TIMER_H #ifndef __TIMER_H
#define __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 /* 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 ** 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 */ extern TimerClientData JunkClientData; /* for use when you don't care */
/* The TimerProc gets called when the timer expires. It gets passed /* 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. ** 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. */ /* The Timer struct. */
typedef struct TimerStruct typedef struct TimerStruct
@ -58,7 +59,7 @@ typedef struct TimerStruct
TimerClientData client_data; TimerClientData client_data;
int64_t usecs; int64_t usecs;
int periodic; int periodic;
struct timeval time; struct iperf_time time;
struct TimerStruct* prev; struct TimerStruct* prev;
struct TimerStruct* next; struct TimerStruct* next;
int hash; int hash;
@ -66,22 +67,22 @@ typedef struct TimerStruct
/* Set up a timer, either periodic or one-shot. Returns (Timer*) 0 on errors. */ /* Set up a timer, either periodic or one-shot. Returns (Timer*) 0 on errors. */
extern Timer* tmr_create( 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 ); int64_t usecs, int periodic );
/* Returns a timeout indicating how long until the next timer triggers. You /* 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 ** can just put the call to this routine right in your select(). Returns
** (struct timeval*) 0 if no timers are pending. ** (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, /* Run the list of timers. Your main program needs to call this every so often,
** or as indicated by tmr_timeout(). ** 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. */ /* 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 /* Deschedule a timer. Note that non-periodic timers are automatically
** descheduled when they run, so you don't have to call this on them. ** descheduled when they run, so you don't have to call this on them.