1
1

Add initial portable time abstraction

Этот коммит содержится в:
Ben Fox-Moore 2018-05-16 23:49:45 +02:00
родитель 829d619ab4
Коммит cde81d7640
17 изменённых файлов: 455 добавлений и 140 удалений

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

@ -13090,6 +13090,75 @@ $as_echo "#define HAVE_SO_MAX_PACING_RATE 1" >>confdefs.h
fi
# Check if we need -lrt for clock_gettime
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
$as_echo_n "checking for library containing clock_gettime... " >&6; }
if ${ac_cv_search_clock_gettime+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char clock_gettime ();
int
main ()
{
return clock_gettime ();
;
return 0;
}
_ACEOF
for ac_lib in '' rt posix4; do
if test -z "$ac_lib"; then
ac_res="none required"
else
ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
fi
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_search_clock_gettime=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if ${ac_cv_search_clock_gettime+:} false; then :
break
fi
done
if ${ac_cv_search_clock_gettime+:} false; then :
else
ac_cv_search_clock_gettime=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5
$as_echo "$ac_cv_search_clock_gettime" >&6; }
ac_res=$ac_cv_search_clock_gettime
if test "$ac_res" != no; then :
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
fi
# Check for clock_gettime support
for ac_func in clock_gettime
do :
ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
if test "x$ac_cv_func_clock_gettime" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_CLOCK_GETTIME 1
_ACEOF
fi
done
ac_config_files="$ac_config_files Makefile src/Makefile src/version.h examples/Makefile iperf3.spec"

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

@ -182,5 +182,9 @@ if test "x$iperf3_cv_header_so_max_pacing_rate" = "xyes"; then
AC_DEFINE([HAVE_SO_MAX_PACING_RATE], [1], [Have SO_MAX_PACING_RATE sockopt.])
fi
# Check if we need -lrt for clock_gettime
AC_SEARCH_LIBS(clock_gettime, [rt posix4])
# Check for clock_gettime support
AC_CHECK_FUNCS([clock_gettime])
AC_OUTPUT([Makefile src/Makefile src/version.h examples/Makefile iperf3.spec])

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

@ -27,6 +27,8 @@ libiperf_la_SOURCES = \
iperf_sctp.h \
iperf_util.c \
iperf_util.h \
iperf_time.c \
iperf_time.h \
dscp.c \
net.c \
net.h \

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

@ -142,7 +142,8 @@ libiperf_la_LIBADD =
am_libiperf_la_OBJECTS = cjson.lo iperf_api.lo iperf_error.lo \
iperf_auth.lo iperf_client_api.lo iperf_locale.lo \
iperf_server_api.lo iperf_tcp.lo iperf_udp.lo iperf_sctp.lo \
iperf_util.lo dscp.lo net.lo tcp_info.lo timer.lo units.lo
iperf_util.lo iperf_time.lo dscp.lo net.lo tcp_info.lo \
timer.lo units.lo
libiperf_la_OBJECTS = $(am_libiperf_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -165,6 +166,7 @@ am__objects_1 = iperf3_profile-cjson.$(OBJEXT) \
iperf3_profile-iperf_udp.$(OBJEXT) \
iperf3_profile-iperf_sctp.$(OBJEXT) \
iperf3_profile-iperf_util.$(OBJEXT) \
iperf3_profile-iperf_time.$(OBJEXT) \
iperf3_profile-dscp.$(OBJEXT) iperf3_profile-net.$(OBJEXT) \
iperf3_profile-tcp_info.$(OBJEXT) \
iperf3_profile-timer.$(OBJEXT) iperf3_profile-units.$(OBJEXT)
@ -220,6 +222,7 @@ am__depfiles_remade = ./$(DEPDIR)/cjson.Plo ./$(DEPDIR)/dscp.Plo \
./$(DEPDIR)/iperf3_profile-iperf_sctp.Po \
./$(DEPDIR)/iperf3_profile-iperf_server_api.Po \
./$(DEPDIR)/iperf3_profile-iperf_tcp.Po \
./$(DEPDIR)/iperf3_profile-iperf_time.Po \
./$(DEPDIR)/iperf3_profile-iperf_udp.Po \
./$(DEPDIR)/iperf3_profile-iperf_util.Po \
./$(DEPDIR)/iperf3_profile-main.Po \
@ -230,11 +233,12 @@ am__depfiles_remade = ./$(DEPDIR)/cjson.Plo ./$(DEPDIR)/dscp.Plo \
./$(DEPDIR)/iperf_auth.Plo ./$(DEPDIR)/iperf_client_api.Plo \
./$(DEPDIR)/iperf_error.Plo ./$(DEPDIR)/iperf_locale.Plo \
./$(DEPDIR)/iperf_sctp.Plo ./$(DEPDIR)/iperf_server_api.Plo \
./$(DEPDIR)/iperf_tcp.Plo ./$(DEPDIR)/iperf_udp.Plo \
./$(DEPDIR)/iperf_util.Plo ./$(DEPDIR)/net.Plo \
./$(DEPDIR)/t_timer-t_timer.Po ./$(DEPDIR)/t_units-t_units.Po \
./$(DEPDIR)/t_uuid-t_uuid.Po ./$(DEPDIR)/tcp_info.Plo \
./$(DEPDIR)/timer.Plo ./$(DEPDIR)/units.Plo
./$(DEPDIR)/iperf_tcp.Plo ./$(DEPDIR)/iperf_time.Plo \
./$(DEPDIR)/iperf_udp.Plo ./$(DEPDIR)/iperf_util.Plo \
./$(DEPDIR)/net.Plo ./$(DEPDIR)/t_timer-t_timer.Po \
./$(DEPDIR)/t_units-t_units.Po ./$(DEPDIR)/t_uuid-t_uuid.Po \
./$(DEPDIR)/tcp_info.Plo ./$(DEPDIR)/timer.Plo \
./$(DEPDIR)/units.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@ -619,6 +623,8 @@ libiperf_la_SOURCES = \
iperf_sctp.h \
iperf_util.c \
iperf_util.h \
iperf_time.c \
iperf_time.h \
dscp.c \
net.c \
net.h \
@ -848,6 +854,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_sctp.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_server_api.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_tcp.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_time.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_udp.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-iperf_util.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf3_profile-main.Po@am__quote@ # am--include-marker
@ -863,6 +870,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_sctp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_server_api.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_tcp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_time.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_udp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iperf_util.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/net.Plo@am__quote@ # am--include-marker
@ -1082,6 +1090,20 @@ iperf3_profile-iperf_util.obj: iperf_util.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -c -o iperf3_profile-iperf_util.obj `if test -f 'iperf_util.c'; then $(CYGPATH_W) 'iperf_util.c'; else $(CYGPATH_W) '$(srcdir)/iperf_util.c'; fi`
iperf3_profile-iperf_time.o: iperf_time.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -MT iperf3_profile-iperf_time.o -MD -MP -MF $(DEPDIR)/iperf3_profile-iperf_time.Tpo -c -o iperf3_profile-iperf_time.o `test -f 'iperf_time.c' || echo '$(srcdir)/'`iperf_time.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/iperf3_profile-iperf_time.Tpo $(DEPDIR)/iperf3_profile-iperf_time.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iperf_time.c' object='iperf3_profile-iperf_time.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -c -o iperf3_profile-iperf_time.o `test -f 'iperf_time.c' || echo '$(srcdir)/'`iperf_time.c
iperf3_profile-iperf_time.obj: iperf_time.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -MT iperf3_profile-iperf_time.obj -MD -MP -MF $(DEPDIR)/iperf3_profile-iperf_time.Tpo -c -o iperf3_profile-iperf_time.obj `if test -f 'iperf_time.c'; then $(CYGPATH_W) 'iperf_time.c'; else $(CYGPATH_W) '$(srcdir)/iperf_time.c'; fi`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/iperf3_profile-iperf_time.Tpo $(DEPDIR)/iperf3_profile-iperf_time.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='iperf_time.c' object='iperf3_profile-iperf_time.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -c -o iperf3_profile-iperf_time.obj `if test -f 'iperf_time.c'; then $(CYGPATH_W) 'iperf_time.c'; else $(CYGPATH_W) '$(srcdir)/iperf_time.c'; fi`
iperf3_profile-dscp.o: dscp.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iperf3_profile_CFLAGS) $(CFLAGS) -MT iperf3_profile-dscp.o -MD -MP -MF $(DEPDIR)/iperf3_profile-dscp.Tpo -c -o iperf3_profile-dscp.o `test -f 'dscp.c' || echo '$(srcdir)/'`dscp.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/iperf3_profile-dscp.Tpo $(DEPDIR)/iperf3_profile-dscp.Po
@ -1632,6 +1654,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_tcp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_time.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_udp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_util.Po
-rm -f ./$(DEPDIR)/iperf3_profile-main.Po
@ -1647,6 +1670,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/iperf_sctp.Plo
-rm -f ./$(DEPDIR)/iperf_server_api.Plo
-rm -f ./$(DEPDIR)/iperf_tcp.Plo
-rm -f ./$(DEPDIR)/iperf_time.Plo
-rm -f ./$(DEPDIR)/iperf_udp.Plo
-rm -f ./$(DEPDIR)/iperf_util.Plo
-rm -f ./$(DEPDIR)/net.Plo
@ -1714,6 +1738,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_sctp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_server_api.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_tcp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_time.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_udp.Po
-rm -f ./$(DEPDIR)/iperf3_profile-iperf_util.Po
-rm -f ./$(DEPDIR)/iperf3_profile-main.Po
@ -1729,6 +1754,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/iperf_sctp.Plo
-rm -f ./$(DEPDIR)/iperf_server_api.Plo
-rm -f ./$(DEPDIR)/iperf_tcp.Plo
-rm -f ./$(DEPDIR)/iperf_time.Plo
-rm -f ./$(DEPDIR)/iperf_udp.Plo
-rm -f ./$(DEPDIR)/iperf_util.Plo
-rm -f ./$(DEPDIR)/net.Plo

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

@ -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;

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

@ -1246,14 +1246,16 @@ iperf_set_send_state(struct iperf_test *test, signed char state)
}
void
iperf_check_throttle(struct iperf_stream *sp, struct timeval *nowP)
iperf_check_throttle(struct iperf_stream *sp, struct iperf_time *nowP)
{
struct iperf_time temp_time;
double seconds;
uint64_t bits_per_second;
if (sp->test->done)
return;
seconds = timeval_diff(&sp->result->start_time_fixed, nowP);
iperf_time_diff(&sp->result->start_time_fixed, nowP, &temp_time);
seconds = iperf_time_in_secs(&temp_time);
bits_per_second = sp->result->bytes_sent * 8 / seconds;
if (bits_per_second < sp->test->settings->rate) {
sp->green_light = 1;
@ -1269,7 +1271,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
{
register int multisend, r, streams_active;
register struct iperf_stream *sp;
struct timeval now;
struct iperf_time now;
/* Can we do multisend mode? */
if (test->settings->burst != 0)
@ -1281,7 +1283,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
for (; multisend > 0; --multisend) {
if (test->settings->rate != 0 && test->settings->burst == 0)
gettimeofday(&now, NULL);
iperf_time_now(&now);
streams_active = 0;
SLIST_FOREACH(sp, &test->streams, streams) {
if ((sp->green_light &&
@ -1307,7 +1309,7 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
break;
}
if (test->settings->burst != 0) {
gettimeofday(&now, NULL);
iperf_time_now(&now);
SLIST_FOREACH(sp, &test->streams, streams)
iperf_check_throttle(sp, &now);
}
@ -1343,7 +1345,7 @@ iperf_recv(struct iperf_test *test, fd_set *read_setP)
int
iperf_init_test(struct iperf_test *test)
{
struct timeval now;
struct iperf_time now;
struct iperf_stream *sp;
if (test->protocol->init) {
@ -1352,7 +1354,7 @@ iperf_init_test(struct iperf_test *test)
}
/* Init each stream. */
if (gettimeofday(&now, NULL) < 0) {
if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST;
return -1;
}
@ -1367,7 +1369,7 @@ iperf_init_test(struct iperf_test *test)
}
static void
send_timer_proc(TimerClientData client_data, struct timeval *nowP)
send_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
{
struct iperf_stream *sp = client_data.p;
@ -1381,11 +1383,11 @@ send_timer_proc(TimerClientData client_data, struct timeval *nowP)
int
iperf_create_send_timers(struct iperf_test * test)
{
struct timeval now;
struct iperf_time now;
struct iperf_stream *sp;
TimerClientData cd;
if (gettimeofday(&now, NULL) < 0) {
if (iperf_time_now(&now) < 0) {
i_errno = IEINITTEST;
return -1;
}
@ -1393,7 +1395,7 @@ iperf_create_send_timers(struct iperf_test * test)
sp->green_light = 1;
if (test->settings->rate != 0) {
cd.p = sp;
sp->send_timer = tmr_create((struct timeval*) 0, send_timer_proc, cd, test->settings->pacing_timer, 1);
sp->send_timer = tmr_create(NULL, send_timer_proc, cd, test->settings->pacing_timer, 1);
if (sp->send_timer == NULL) {
i_errno = IEINITTEST;
return -1;
@ -1689,6 +1691,7 @@ send_results(struct iperf_test *test)
int sender_has_retransmits;
iperf_size_t bytes_transferred;
int retransmits;
struct iperf_time temp_time;
double start_time, end_time;
j = cJSON_CreateObject();
@ -1758,8 +1761,10 @@ send_results(struct iperf_test *test)
cJSON_AddNumberToObject(j_stream, "errors", sp->cnt_error);
cJSON_AddNumberToObject(j_stream, "packets", sp->packet_count);
start_time = timeval_diff(&sp->result->start_time, &sp->result->start_time);
end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time);
iperf_time_diff(&sp->result->start_time, &sp->result->start_time, &temp_time);
start_time = iperf_time_in_secs(&temp_time);
iperf_time_diff(&sp->result->start_time, &sp->result->end_time, &temp_time);
end_time = iperf_time_in_secs(&temp_time);
cJSON_AddNumberToObject(j_stream, "start_time", start_time);
cJSON_AddNumberToObject(j_stream, "end_time", end_time);
@ -2430,13 +2435,13 @@ iperf_reset_test(struct iperf_test *test)
void
iperf_reset_stats(struct iperf_test *test)
{
struct timeval now;
struct iperf_time now;
struct iperf_stream *sp;
struct iperf_stream_result *rp;
test->bytes_sent = 0;
test->blocks_sent = 0;
gettimeofday(&now, NULL);
iperf_time_now(&now);
SLIST_FOREACH(sp, &test->streams, streams) {
sp->omitted_packet_count = sp->packet_count;
sp->omitted_cnt_error = sp->cnt_error;
@ -2469,6 +2474,7 @@ iperf_stats_callback(struct iperf_test *test)
struct iperf_stream *sp;
struct iperf_stream_result *rp = NULL;
struct iperf_interval_results *irp, temp;
struct iperf_time temp_time;
temp.omitted = test->omitting;
SLIST_FOREACH(sp, &test->streams, streams) {
@ -2479,14 +2485,14 @@ iperf_stats_callback(struct iperf_test *test)
irp = TAILQ_LAST(&rp->interval_results, irlisthead);
/* result->end_time contains timestamp of previous interval */
if ( irp != NULL ) /* not the 1st interval */
memcpy(&temp.interval_start_time, &rp->end_time, sizeof(struct timeval));
memcpy(&temp.interval_start_time, &rp->end_time, sizeof(struct iperf_time));
else /* or use timestamp from beginning */
memcpy(&temp.interval_start_time, &rp->start_time, sizeof(struct timeval));
memcpy(&temp.interval_start_time, &rp->start_time, sizeof(struct iperf_time));
/* now save time of end of this interval */
gettimeofday(&rp->end_time, NULL);
memcpy(&temp.interval_end_time, &rp->end_time, sizeof(struct timeval));
temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time);
//temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time);
iperf_time_now(&rp->end_time);
memcpy(&temp.interval_end_time, &rp->end_time, sizeof(struct iperf_time));
iperf_time_diff(&temp.interval_start_time, &temp.interval_end_time, &temp_time);
temp.interval_duration = iperf_time_in_secs(&temp_time);
if (test->protocol->id == Ptcp) {
if ( has_tcpinfo()) {
save_tcpinfo(sp, &temp);
@ -2553,6 +2559,7 @@ iperf_print_intermediate(struct iperf_test *test)
double bandwidth;
int retransmits = 0;
double start_time, end_time;
struct iperf_time temp_time;
cJSON *json_interval;
cJSON *json_interval_streams;
int total_packets = 0, lost_packets = 0;
@ -2575,8 +2582,8 @@ iperf_print_intermediate(struct iperf_test *test)
SLIST_FOREACH(sp, &test->streams, streams) {
irp = TAILQ_LAST(&sp->result->interval_results, irlisthead);
if (irp) {
double interval_len = timeval_diff(&irp->interval_start_time,
&irp->interval_end_time);
iperf_time_diff(&irp->interval_start_time, &irp->interval_end_time, &temp_time);
double interval_len = iperf_time_in_secs(&temp_time);
if (test->debug) {
printf("interval_len %f bytes_transferred %" PRIu64 "\n", interval_len, irp->bytes_transferred);
}
@ -2641,14 +2648,16 @@ iperf_print_intermediate(struct iperf_test *test)
sp = SLIST_FIRST(&test->streams); /* reset back to 1st stream */
/* Only do this of course if there was a first stream */
if (sp) {
irp = TAILQ_LAST(&sp->result->interval_results, irlisthead); /* use 1st stream for timing info */
irp = TAILQ_LAST(&sp->result->interval_results, irlisthead); /* use 1st stream for timing info */
unit_snprintf(ubuf, UNIT_LEN, (double) bytes, 'A');
bandwidth = (double) bytes / (double) irp->interval_duration;
unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
unit_snprintf(ubuf, UNIT_LEN, (double) bytes, 'A');
bandwidth = (double) bytes / (double) irp->interval_duration;
unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
start_time = timeval_diff(&sp->result->start_time,&irp->interval_start_time);
end_time = timeval_diff(&sp->result->start_time,&irp->interval_end_time);
iperf_time_diff(&sp->result->start_time,&irp->interval_start_time, &temp_time);
start_time = iperf_time_in_secs(&temp_time);
iperf_time_diff(&sp->result->start_time,&irp->interval_end_time, &temp_time);
end_time = iperf_time_in_secs(&temp_time);
if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
if (test->sender && test->sender_has_retransmits) {
/* Interval sum, TCP with retransmits. */
@ -2710,6 +2719,7 @@ iperf_print_results(struct iperf_test *test)
iperf_size_t bytes_received, total_received = 0;
double start_time, end_time = 0.0, avg_jitter = 0.0, lost_percent = 0.0;
double sender_time = 0.0, receiver_time = 0.0;
struct iperf_time temp_time;
double bandwidth;
/* print final summary for all intervals */
@ -2747,7 +2757,8 @@ iperf_print_results(struct iperf_test *test)
* basically emulating what iperf 3.1 did.
*/
if (sp) {
end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time);
iperf_time_diff(&sp->result->start_time, &sp->result->end_time, &temp_time);
end_time = iperf_time_in_secs(&temp_time);
if (test->sender) {
sp->result->sender_time = end_time;
if (sp->result->receiver_time == 0.0) {
@ -3142,6 +3153,7 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
char nbuf[UNIT_LEN];
char cbuf[UNIT_LEN];
double st = 0., et = 0.;
struct iperf_time temp_time;
struct iperf_interval_results *irp = NULL;
double bandwidth, lost_percent;
@ -3157,7 +3169,7 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
** else if there's more than one stream, print the separator;
** else nothing.
*/
if (timeval_equals(&sp->result->start_time, &irp->interval_start_time)) {
if (iperf_time_compare(&sp->result->start_time, &irp->interval_start_time) == 0) {
if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
if (test->sender && test->sender_has_retransmits)
iperf_printf(test, "%s", report_bw_retrans_cwnd_header);
@ -3183,8 +3195,10 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
}
unit_snprintf(nbuf, UNIT_LEN, bandwidth, test->settings->unit_format);
st = timeval_diff(&sp->result->start_time, &irp->interval_start_time);
et = timeval_diff(&sp->result->start_time, &irp->interval_end_time);
iperf_time_diff(&sp->result->start_time, &irp->interval_start_time, &temp_time);
st = iperf_time_in_secs(&temp_time);
iperf_time_diff(&sp->result->start_time, &irp->interval_end_time, &temp_time);
et = iperf_time_in_secs(&temp_time);
if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
if (test->sender && test->sender_has_retransmits) {

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

@ -42,6 +42,7 @@ struct iperf_test;
struct iperf_stream_result;
struct iperf_interval_results;
struct iperf_stream;
struct iperf_time;
/* default settings */
#define Ptcp SOCK_STREAM
@ -240,7 +241,7 @@ void print_tcpinfo(struct iperf_test *test);
void build_tcpinfo_message(struct iperf_interval_results *r, char *message);
int iperf_set_send_state(struct iperf_test *test, signed char state);
void iperf_check_throttle(struct iperf_stream *sp, struct timeval *nowP);
void iperf_check_throttle(struct iperf_stream *sp, struct iperf_time *nowP);
int iperf_send(struct iperf_test *, fd_set *) /* __attribute__((hot)) */;
int iperf_recv(struct iperf_test *, fd_set *);
void iperf_catch_sigend(void (*handler)(int));

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

@ -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 Обычный файл
Просмотреть файл

@ -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 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");

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

@ -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 );
}

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

@ -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.