Merge branch 'iperf_time' of https://github.com/accelleran/iperf into accelleran-iperf_time
diff --git a/configure b/configure
index 0fadd03..9f9023e 100755
--- a/configure
+++ b/configure
@@ -13111,6 +13111,75 @@
 
 fi
 
+# Check if we need -lrt for clock_gettime
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
+$as_echo_n "checking for library containing clock_gettime... " >&6; }
+if ${ac_cv_search_clock_gettime+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char clock_gettime ();
+int
+main ()
+{
+return clock_gettime ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' rt posix4; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_clock_gettime=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_clock_gettime+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_clock_gettime+:} false; then :
+
+else
+  ac_cv_search_clock_gettime=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_clock_gettime" >&5
+$as_echo "$ac_cv_search_clock_gettime" >&6; }
+ac_res=$ac_cv_search_clock_gettime
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+# Check for clock_gettime support
+for ac_func in clock_gettime
+do :
+  ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime"
+if test "x$ac_cv_func_clock_gettime" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_CLOCK_GETTIME 1
+_ACEOF
+
+fi
+done
+
 
 ac_config_files="$ac_config_files Makefile src/Makefile src/version.h examples/Makefile iperf3.spec"
 
diff --git a/configure.ac b/configure.ac
index c00aabc..7e36a1d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -189,5 +189,9 @@
     AC_DEFINE([HAVE_SO_MAX_PACING_RATE], [1], [Have SO_MAX_PACING_RATE sockopt.])
 fi
 
+# Check if we need -lrt for clock_gettime
+AC_SEARCH_LIBS(clock_gettime, [rt posix4])
+# Check for clock_gettime support
+AC_CHECK_FUNCS([clock_gettime])
 
 AC_OUTPUT([Makefile src/Makefile src/version.h examples/Makefile iperf3.spec])
diff --git a/src/Makefile.am b/src/Makefile.am
index e95722d..5be8562 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,7 +31,9 @@
                         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 \
diff --git a/src/Makefile.in b/src/Makefile.in
index a584c59..d6950b0 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -147,7 +147,8 @@
 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@)
@@ -177,6 +178,7 @@
 	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 +241,7 @@
 	./$(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 \
@@ -639,7 +642,9 @@
                         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 +882,7 @@
 @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 +898,7 @@
 @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 +1119,20 @@
 @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 +1704,7 @@
 	-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 +1720,7 @@
 	-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 +1789,7 @@
 	-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 +1805,7 @@
 	-rm -f ./$(DEPDIR)/iperf_sctp.Plo
 	-rm -f ./$(DEPDIR)/iperf_server_api.Plo
 	-rm -f ./$(DEPDIR)/iperf_tcp.Plo
+	-rm -f ./$(DEPDIR)/iperf_time.Plo
 	-rm -f ./$(DEPDIR)/iperf_udp.Plo
 	-rm -f ./$(DEPDIR)/iperf_util.Plo
 	-rm -f ./$(DEPDIR)/net.Plo
diff --git a/src/iperf.h b/src/iperf.h
index 5c36123..26e4f4f 100755
--- a/src/iperf.h
+++ b/src/iperf.h
@@ -61,6 +61,7 @@
 #include "timer.h"
 #include "queue.h"
 #include "cjson.h"
+#include "iperf_time.h"
 
 #if defined(HAVE_SSL)
 #include <openssl/bio.h>
@@ -72,8 +73,8 @@
 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 @@
     int stream_sum_rtt;
     int stream_count_rtt;
     int stream_max_snd_cwnd;
-    struct timeval start_time;
-    struct timeval end_time;
-    struct timeval start_time_fixed;
+    struct iperf_time start_time;
+    struct iperf_time end_time;
+    struct iperf_time start_time_fixed;
     double sender_time;
     double receiver_time;
     TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results;
diff --git a/src/iperf_api.c b/src/iperf_api.c
index 18fde62..d6c4717 100755
--- a/src/iperf_api.c
+++ b/src/iperf_api.c
@@ -1304,14 +1304,16 @@
 }
 
 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 @@
 {
     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 @@
 
     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 @@
 	    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 @@
 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 @@
     }
 
     /* Init each stream. */
-    if (gettimeofday(&now, NULL) < 0) {
+    if (iperf_time_now(&now) < 0) {
 	i_errno = IEINITTEST;
 	return -1;
     }
@@ -1425,7 +1427,7 @@
 }
 
 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 @@
 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 @@
         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 @@
     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 @@
 		    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 @@
 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 @@
     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 @@
 	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 @@
     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 @@
     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 @@
         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_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 @@
      * 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 @@
     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 @@
 	    ** 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 @@
     }
     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) {
diff --git a/src/iperf_api.h b/src/iperf_api.h
index 82322ef..54936ab 100755
--- a/src/iperf_api.h
+++ b/src/iperf_api.h
@@ -42,6 +42,7 @@
 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 build_tcpinfo_message(struct iperf_interval_results *r, char *message);
 
 int iperf_set_send_state(struct iperf_test *test, signed char state);
-void iperf_check_throttle(struct iperf_stream *sp, struct timeval *nowP);
+void iperf_check_throttle(struct iperf_stream *sp, struct iperf_time *nowP);
 int iperf_send(struct iperf_test *, fd_set *) /* __attribute__((hot)) */;
 int iperf_recv(struct iperf_test *, fd_set *);
 void iperf_catch_sigend(void (*handler)(int));
diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c
index 3ca6b06..aca6826 100644
--- a/src/iperf_client_api.c
+++ b/src/iperf_client_api.c
@@ -41,6 +41,7 @@
 #include "iperf_api.h"
 #include "iperf_util.h"
 #include "iperf_locale.h"
+#include "iperf_time.h"
 #include "net.h"
 #include "timer.h"
 
@@ -116,7 +117,7 @@
 }
 
 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 @@
 }
 
 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 @@
 }
 
 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 @@
 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 @@
 }
 
 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 @@
 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 @@
     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 @@
     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 @@
 	    }
 
             /* Run the timers. */
-            (void) gettimeofday(&now, NULL);
+            iperf_time_now(&now);
             tmr_run(&now);
 
 	    /* Is the test done yet? */
diff --git a/src/iperf_config.h.in b/src/iperf_config.h.in
index 2d13f98..e543cbd 100644
--- a/src/iperf_config.h.in
+++ b/src/iperf_config.h.in
@@ -1,5 +1,8 @@
 /* src/iperf_config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
 /* Define to 1 if you have the `cpuset_setaffinity' function. */
 #undef HAVE_CPUSET_SETAFFINITY
 
diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c
index fabee60..78c7099 100644
--- a/src/iperf_server_api.c
+++ b/src/iperf_server_api.c
@@ -54,6 +54,7 @@
 #include "iperf_tcp.h"
 #include "iperf_util.h"
 #include "timer.h"
+#include "iperf_time.h"
 #include "net.h"
 #include "units.h"
 #include "iperf_util.h"
@@ -223,7 +224,7 @@
 }
 
 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 @@
 }
 
 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 @@
 }
 
 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 @@
 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 @@
 }
 
 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 @@
 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 @@
 #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 @@
         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 @@
 	if (result == 0 ||
 	    (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0)) {
 	    /* Run the timers. */
-	    (void) gettimeofday(&now, NULL);
+	    iperf_time_now(&now);
 	    tmr_run(&now);
 	}
     }
diff --git a/src/iperf_time.c b/src/iperf_time.c
new file mode 100644
index 0000000..0ca3790
--- /dev/null
+++ b/src/iperf_time.c
@@ -0,0 +1,156 @@
+/*
+ * iperf, Copyright (c) 2014-2018, The Regents of the University of
+ * California, through Lawrence Berkeley National Laboratory (subject
+ * to receipt of any required approvals from the U.S. Dept. of
+ * Energy).  All rights reserved.
+ *
+ * If you have questions about your rights to use or distribute this
+ * software, please contact Berkeley Lab's Technology Transfer
+ * Department at TTD@lbl.gov.
+ *
+ * NOTICE.  This software is owned by the U.S. Department of Energy.
+ * As such, the U.S. Government has been granted for itself and others
+ * acting on its behalf a paid-up, nonexclusive, irrevocable,
+ * worldwide license in the Software to reproduce, prepare derivative
+ * works, and perform publicly and display publicly.  Beginning five
+ * (5) years after the date permission to assert copyright is obtained
+ * from the U.S. Department of Energy, and subject to any subsequent
+ * five (5) year renewals, the U.S. Government is granted for itself
+ * and others acting on its behalf a paid-up, nonexclusive,
+ * irrevocable, worldwide license in the Software to reproduce,
+ * prepare derivative works, distribute copies to the public, perform
+ * publicly and display publicly, and to permit others to do so.
+ *
+ * This code is distributed under a BSD style license, see the LICENSE
+ * file for complete information.
+ */
+
+
+#include <stddef.h>
+
+#include "iperf_config.h"
+#include "iperf_time.h"
+
+#ifdef HAVE_CLOCK_GETTIME
+
+#include <time.h>
+
+int
+iperf_time_now(struct iperf_time *time1)
+{
+    struct timespec ts;
+    int result;
+    result = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+    if (result == 0) {
+        time1->secs = (uint32_t) ts.tv_sec;
+        time1->usecs = (uint32_t) ts.tv_nsec / 1000;
+    }
+    return result;
+}
+
+#else
+
+#include <sys/time.h>
+
+int
+iperf_time_now(struct iperf_time *time1)
+{
+    struct timeval tv;
+    int result;
+    result = gettimeofday(&tv, NULL);
+    time1->secs = tv.tv_sec;
+    time1->usecs = tv.tv_usec;
+    return result;
+}
+
+#endif
+
+/* iperf_time_add_usecs
+ *
+ * Add a number of microseconds to a iperf_time.
+ */
+void
+iperf_time_add_usecs(struct iperf_time *time1, uint64_t usecs)
+{
+    time1->secs += usecs / 1000000L;
+    time1->usecs += usecs % 1000000L;
+    if ( time1->usecs >= 1000000L ) {
+        time1->secs += time1->usecs / 1000000L;
+        time1->usecs %= 1000000L;
+    }
+}
+
+uint64_t
+iperf_time_in_usecs(struct iperf_time *time)
+{
+    return time->secs * 1000000LL + time->usecs;
+}
+
+double
+iperf_time_in_secs(struct iperf_time *time)
+{
+    return time->secs + time->usecs / 1000000.0; 
+}
+
+/* iperf_time_compare
+ *
+ * Compare two timestamps
+ * 
+ * Returns -1 if time1 is earlier, 1 if time1 is later,
+ * or 0 if the timestamps are equal.
+ */
+int
+iperf_time_compare(struct iperf_time *time1, struct iperf_time *time2)
+{
+    if (time1->secs < time2->secs)
+        return -1;
+    if (time1->secs > time2->secs)
+        return 1;
+    if (time1->usecs < time2->usecs)
+        return -1;
+    if (time1->usecs > time2->usecs)
+        return 1;
+    return 0;
+}
+
+/* iperf_time_diff
+ *
+ * Calculates the time from time2 to time1, assuming time1 is later than time2.
+ * The diff will always be positive, so the return value should be checked
+ * to determine if time1 was earlier than time2.
+ *
+ * Returns 1 if the time1 is less than or equal to time2, otherwise 0.
+ */
+int 
+iperf_time_diff(struct iperf_time *time1, struct iperf_time *time2, struct iperf_time *diff)
+{
+    int past = 0;
+    int cmp = 0;
+
+    cmp = iperf_time_compare(time1, time2);
+    if (cmp == 0) {
+        diff->secs = 0;
+        diff->usecs = 0;
+        past = 1;
+    } 
+    else if (cmp == 1) {
+        diff->secs = time1->secs - time2->secs;
+        diff->usecs = time1->usecs;
+        if (diff->usecs < time2->usecs) {
+            diff->secs -= 1;
+            diff->usecs += 1000000;
+        }
+        diff->usecs = diff->usecs - time2->usecs;
+    } else {
+        diff->secs = time2->secs - time1->secs;
+        diff->usecs = time2->usecs;
+        if (diff->usecs < time1->usecs) {
+            diff->secs -= 1;
+            diff->usecs += 1000000;
+        }
+        diff->usecs = diff->usecs - time1->usecs;
+        past = 1;
+    }
+
+    return past;
+}
diff --git a/src/iperf_time.h b/src/iperf_time.h
new file mode 100644
index 0000000..588ee26
--- /dev/null
+++ b/src/iperf_time.h
@@ -0,0 +1,49 @@
+/*
+ * iperf, Copyright (c) 2014-2018, The Regents of the University of
+ * California, through Lawrence Berkeley National Laboratory (subject
+ * to receipt of any required approvals from the U.S. Dept. of
+ * Energy).  All rights reserved.
+ *
+ * If you have questions about your rights to use or distribute this
+ * software, please contact Berkeley Lab's Technology Transfer
+ * Department at TTD@lbl.gov.
+ *
+ * NOTICE.  This software is owned by the U.S. Department of Energy.
+ * As such, the U.S. Government has been granted for itself and others
+ * acting on its behalf a paid-up, nonexclusive, irrevocable,
+ * worldwide license in the Software to reproduce, prepare derivative
+ * works, and perform publicly and display publicly.  Beginning five
+ * (5) years after the date permission to assert copyright is obtained
+ * from the U.S. Department of Energy, and subject to any subsequent
+ * five (5) year renewals, the U.S. Government is granted for itself
+ * and others acting on its behalf a paid-up, nonexclusive,
+ * irrevocable, worldwide license in the Software to reproduce,
+ * prepare derivative works, distribute copies to the public, perform
+ * publicly and display publicly, and to permit others to do so.
+ *
+ * This code is distributed under a BSD style license, see the LICENSE
+ * file for complete information.
+ */
+#ifndef __IPERF_TIME_H
+#define __IPERF_TIME_H
+
+#include <stdint.h>
+
+struct iperf_time {
+    uint32_t secs;
+    uint32_t usecs;
+};
+
+int iperf_time_now(struct iperf_time *time1);
+
+void iperf_time_add_usecs(struct iperf_time *time1, uint64_t usecs);
+
+int iperf_time_compare(struct iperf_time *time1, struct iperf_time *time2);
+
+int iperf_time_diff(struct iperf_time *time1, struct iperf_time *time2, struct iperf_time *diff);
+
+uint64_t iperf_time_in_usecs(struct iperf_time *time);
+
+double iperf_time_in_secs(struct iperf_time *time);
+
+#endif
diff --git a/src/iperf_udp.c b/src/iperf_udp.c
index 33f367f..3d37dab 100644
--- a/src/iperf_udp.c
+++ b/src/iperf_udp.c
@@ -66,7 +66,7 @@
     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 @@
 	    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 @@
 	    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 @@
 	 * 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 @@
 {
     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 @@
 	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 @@
 
 	uint32_t  sec, usec, pcount;
 
-	sec = htonl(before.tv_sec);
-	usec = htonl(before.tv_usec);
+	sec = htonl(before.secs);
+	usec = htonl(before.usecs);
 	pcount = htonl(sp->packet_count);
 	
 	memcpy(sp->buffer, &sec, sizeof(sec));
diff --git a/src/iperf_util.c b/src/iperf_util.c
index 3922def..c5af476 100644
--- a/src/iperf_util.c
+++ b/src/iperf_util.c
@@ -189,10 +189,10 @@
 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 @@
     double systemdiff;
 
     if (pcpu == NULL) {
-        gettimeofday(&last, NULL);
+        iperf_time_now(&last);
         clast = clock();
 	getrusage(RUSAGE_SELF, &rlast);
         return;
     }
 
-    gettimeofday(&temp, NULL);
+    iperf_time_now(&now);
     ctemp = clock();
     getrusage(RUSAGE_SELF, &rtemp);
 
-    timediff = ((temp.tv_sec * 1000000.0 + temp.tv_usec) -
-                (last.tv_sec * 1000000.0 + last.tv_usec));
+    iperf_time_diff(&now, &last, &temp_time);
+    timediff = iperf_time_in_secs(&temp_time);
+
     userdiff = ((rtemp.ru_utime.tv_sec * 1000000.0 + rtemp.ru_utime.tv_usec) -
                 (rlast.ru_utime.tv_sec * 1000000.0 + rlast.ru_utime.tv_usec));
     systemdiff = ((rtemp.ru_stime.tv_sec * 1000000.0 + rtemp.ru_stime.tv_usec) -
diff --git a/src/t_timer.c b/src/t_timer.c
index ed74672..9598594 100644
--- a/src/t_timer.c
+++ b/src/t_timer.c
@@ -35,13 +35,14 @@
 #include <sys/time.h>
 
 #include "timer.h"
+#include "iperf_time.h"
 
 
 static int flag;
 
 
 static void
-timer_proc( TimerClientData client_data, struct timeval* nowP )
+timer_proc( TimerClientData client_data, struct iperf_time* nowP )
 {
     flag = 1;
 }
@@ -53,7 +54,7 @@
     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 @@
 
     sleep(2);
 
-    tmr_run((struct timeval*) 0);
+    tmr_run(NULL);
     if (flag)
     {
 	printf("timer should not have expired\n");
@@ -70,7 +71,7 @@
     }
     sleep(1);
 
-    tmr_run((struct timeval*) 0);
+    tmr_run(NULL);
     if (!flag)
     {
 	printf("timer should have expired\n");
diff --git a/src/timer.c b/src/timer.c
index bfc52e4..33923c7 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -31,7 +31,7 @@
 #include <stdlib.h>
 
 #include "timer.h"
-
+#include "iperf_time.h"
 
 static Timer* timers = NULL;
 static Timer* free_timers = NULL;
@@ -41,19 +41,19 @@
 
 
 /* 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 @@
 	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 @@
 	    /* 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 @@
 }
 
 
-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 @@
     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 @@
 
 
 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 @@
 
 
 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 @@
 	/* 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 @@
 
 
 void
-tmr_reset( struct timeval* nowP, Timer* t )
+tmr_reset( struct iperf_time* nowP, Timer* t )
 {
-    struct timeval now;
+    struct iperf_time now;
     
     getnow( nowP, &now );
     t->time = now;
-    add_usecs( &t->time, t->usecs );
+    iperf_time_add_usecs( &t->time, t->usecs );
     list_resort( t );
 }
 
diff --git a/src/timer.h b/src/timer.h
index 0f9c5eb..301cdf3 100644
--- a/src/timer.h
+++ b/src/timer.h
@@ -30,7 +30,8 @@
 #ifndef __TIMER_H
 #define __TIMER_H
 
-#include <sys/time.h>
+#include <time.h>
+#include "iperf_time.h"
 
 /* TimerClientData is an opaque value that tags along with a timer.  The
 ** client can use it for whatever, and it gets passed to the callback when
@@ -46,10 +47,10 @@
 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 @@
     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 @@
 
 /* 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.