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.
Этот коммит содержится в:
Коммит
a68171340f
69
configure
поставляемый
69
configure
поставляемый
@ -13111,6 +13111,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"
|
||||
|
||||
|
@ -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.])
|
||||
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])
|
||||
|
@ -31,7 +31,9 @@ libiperf_la_SOURCES = \
|
||||
iperf_sctp.h \
|
||||
iperf_util.c \
|
||||
iperf_util.h \
|
||||
dscp.c \
|
||||
iperf_time.c \
|
||||
iperf_time.h \
|
||||
dscp.c \
|
||||
net.c \
|
||||
net.h \
|
||||
portable_endian.h \
|
||||
|
@ -147,7 +147,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@)
|
||||
@ -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_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_util.h dscp.c net.c net.h portable_endian.h queue.h \
|
||||
tcp_info.c timer.c timer.h units.c units.h version.h
|
||||
iperf_util.h iperf_time.c iperf_time.h dscp.c net.c net.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) \
|
||||
iperf3_profile-iperf_api.$(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_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)
|
||||
@ -239,6 +242,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 \
|
||||
@ -249,12 +253,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_api-t_api.Po ./$(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_api-t_api.Po \
|
||||
./$(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)
|
||||
@ -639,7 +643,9 @@ libiperf_la_SOURCES = \
|
||||
iperf_sctp.h \
|
||||
iperf_util.c \
|
||||
iperf_util.h \
|
||||
dscp.c \
|
||||
iperf_time.c \
|
||||
iperf_time.h \
|
||||
dscp.c \
|
||||
net.c \
|
||||
net.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_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
|
||||
@ -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_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
|
||||
@ -1112,6 +1120,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
|
||||
@ -1683,6 +1705,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
|
||||
@ -1698,6 +1721,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
|
||||
@ -1766,6 +1790,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
|
||||
@ -1781,6 +1806,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
|
||||
|
11
src/iperf.h
11
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;
|
||||
|
@ -1304,14 +1304,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;
|
||||
@ -1327,7 +1329,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)
|
||||
@ -1339,7 +1341,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 &&
|
||||
@ -1365,7 +1367,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);
|
||||
}
|
||||
@ -1401,7 +1403,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) {
|
||||
@ -1410,7 +1412,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;
|
||||
}
|
||||
@ -1425,7 +1427,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;
|
||||
|
||||
@ -1439,11 +1441,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;
|
||||
}
|
||||
@ -1451,7 +1453,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;
|
||||
@ -1749,6 +1751,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();
|
||||
@ -1818,8 +1821,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);
|
||||
|
||||
@ -2490,13 +2495,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;
|
||||
@ -2529,6 +2534,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) {
|
||||
@ -2539,14 +2545,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);
|
||||
@ -2613,6 +2619,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;
|
||||
@ -2635,8 +2642,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);
|
||||
}
|
||||
@ -2701,14 +2708,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_has_retransmits == 1) {
|
||||
/* Interval sum, TCP with retransmits. */
|
||||
@ -2770,6 +2779,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 */
|
||||
@ -2807,7 +2817,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) {
|
||||
@ -3202,6 +3213,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;
|
||||
|
||||
@ -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 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_has_retransmits == 1)
|
||||
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);
|
||||
|
||||
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_has_retransmits == 1) {
|
||||
|
@ -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
|
||||
@ -247,7 +248,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));
|
||||
|
@ -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? */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
156
src/iperf_time.c
Обычный файл
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
Обычный файл
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 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));
|
||||
|
@ -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) -
|
||||
|
@ -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");
|
||||
|
68
src/timer.c
68
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 );
|
||||
}
|
||||
|
||||
|
17
src/timer.h
17
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.
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user