]> granicus.if.org Git - curl/commitdiff
Internal time differences now use monotonic time source if available.
authorYang Tse <yangsita@gmail.com>
Fri, 9 May 2008 16:31:51 +0000 (16:31 +0000)
committerYang Tse <yangsita@gmail.com>
Fri, 9 May 2008 16:31:51 +0000 (16:31 +0000)
This also implies the removal of the winmm.lib dependency for WIN32.

17 files changed:
CHANGES
RELEASE-NOTES
configure.ac
docs/INSTALL.devcpp
docs/examples/Makefile.m32
lib/Makefile.Watcom
lib/Makefile.m32
lib/Makefile.vc6
lib/config-win32ce.h
lib/msvcproj.head
lib/select.c
lib/timeval.c
src/Makefile.Watcom
src/Makefile.m32
src/Makefile.vc6
src/curlutil.c
tests/libtest/testutil.c

diff --git a/CHANGES b/CHANGES
index d0e41a5d419a000503fe1e5a8b1e3d2f012bd8e4..8372bd37bf38a802529ecccb9b8809157b080ecd 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,10 @@
                                   Changelog
 
 
+Yang Tse (9 May 2008)
+- Internal time differences now use monotonic time source if available.
+  This also implies the removal of the winmm.lib dependency for WIN32.
+
 Daniel Stenberg (9 May 2008)
 - Stefan Krause reported a busy-looping case when using the multi interface
   and doing CONNECT to a proxy. The app would then busy-loop until the proxy
index 1e85e25fc438a85471eef54480a97052adc85946..15781b3ea060aee0b918ee7249b6867a9a4aad7c 100644 (file)
@@ -33,6 +33,7 @@ This release includes the following bugfixes:
  o microsecond resolution keys for internal splay trees
  o krb4 and krb5 ftp segfault
  o multi interface busy loop for CONNECT requests
+ o internal time differences now use monotonic time source if available
 
 This release includes the following known bugs:
 
index 910a8d160dc86762836993fe826d6b1d9bd99925..8a5988959e7adefdb4d1e2fbd65de19c5bb4426f 100644 (file)
@@ -674,36 +674,6 @@ if test x$CURL_DISABLE_LDAP != x1 ; then
   fi
 fi
 
-dnl **********************************************************************
-dnl Check for the presence of the winmm library.
-dnl **********************************************************************
-
-case $host in
-  *-*-cygwin*)
-    dnl Under Cygwin, winmm exists but is not needed as WIN32 is not #defined
-    dnl and gettimeofday() will be used regardless of the outcome of this test.
-    dnl Skip this test, otherwise -lwinmm will be needlessly added to LIBS
-    dnl (and recorded as such in the .la file, potentially affecting downstream
-    dnl clients of the library.)
-    ;;
-  *)
-    AC_MSG_CHECKING([for timeGetTime in winmm])
-    my_ac_save_LIBS=$LIBS
-    LIBS="-lwinmm $LIBS"
-    AC_TRY_LINK([#include <windef.h>
-                 #include <mmsystem.h>
-                 ],
-                 [timeGetTime();],
-                 [ dnl worked!
-                 AC_MSG_RESULT([yes])
-                 ],
-                 [ dnl failed, restore LIBS
-                 LIBS=$my_ac_save_LIBS
-                 AC_MSG_RESULT(no)]
-               )
-    ;;
-esac
-
 dnl **********************************************************************
 dnl Checks for IPv6
 dnl **********************************************************************
@@ -2006,6 +1976,7 @@ AC_CHECK_FUNCS( strtoll \
                 strcmpi \
                 gethostbyaddr \
                 gettimeofday \
+                clock_gettime \
                 inet_addr \
                 inet_ntoa \
                 inet_pton \
index 8ff4144cc47ce6bc2b52f136b7d452a398fe7757..ed5ed9150240f7504ef3fda1870606eeb4d7bbe3 100644 (file)
@@ -239,7 +239,7 @@ Linker Links
 checked.
 
 3- Include in the white space immediately below the box referred in 2 -lcurl
--lws2_32 -lwinmm.
+-lws2_32.
 
 SSL Files
 ---------
index 470061c4cf5148a952d94080eb86bf90107b55c7..5107c04fea4559526f96d6f54fdf525f38ddc567 100644 (file)
@@ -106,7 +106,7 @@ ifndef USE_LDAP_OPENLDAP
 curl_LDADD += -lwldap32
 endif
 endif
-curl_LDADD += -lws2_32 -lwinmm
+curl_LDADD += -lws2_32
 COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
 
 # Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
index 8e5118ecb147dd8b5b5e5ccf5633de8db3f8a987..ed564c111cbd4a9537a42b9fc8d6284544847adb 100644 (file)
@@ -10,7 +10,7 @@ CC = wcc386
 
 CFLAGS = -3r -mf -d3 -hc -zff -zgf -zq -zm -zc -s -fr=con -w2 -fpi -oilrtfm -bt=nt &
          -bd -d+ -dWIN32 -dCURL_CA_BUNDLE=getenv("CURL_CA_BUNDLE")                 &
-         -dBUILDING_LIBCURL -dWITHOUT_MM_LIB -dHAVE_SPNEGO=1 -dENABLE_IPV6         &
+         -dBUILDING_LIBCURL -dHAVE_SPNEGO=1 -dENABLE_IPV6                          &
          -dDEBUG_THREADING_GETADDRINFO -dDEBUG=1 -dCURLDEBUG -d_WIN32_WINNT=0x0501 &
          -dWINBERAPI=__declspec(cdecl) -dWINLDAPAPI=__declspec(cdecl)              &
          -I. -I..\include
index 6fd8b9b7c28d0c74cce56048a7e47e198b27b8c3..615d07805a6254ea969730b09c1af4a4af1a8078 100644 (file)
@@ -96,7 +96,7 @@ ifndef USE_LDAP_OPENLDAP
 DLL_LIBS += -lwldap32
 endif
 endif
-DLL_LIBS += -lws2_32 -lwinmm
+DLL_LIBS += -lws2_32
 COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
 
 # Makefile.inc provides the CSOURCES and HHEADERS defines
index bce42a6a0a2ae08f260430efbf7c1dcb3434d5bb..5652cb49958c6da04408d361629dd55ce3d5d734 100644 (file)
@@ -66,10 +66,6 @@ WINDOWS_SDK_PATH = "C:\Program Files\Microsoft SDK"
 !ENDIF\r
 !ENDIF\r
 \r
-# Use the high resolution time by default.  Comment this out to use low\r
-# resolution time and not require winmm.lib\r
-USEMM_LIBS = YES\r
-\r
 #############################################################\r
 ## Nothing more to do below this line!\r
 \r
@@ -85,13 +81,9 @@ LFLAGS     = /nologo /machine:$(MACHINE)
 SSLLIBS    = libeay32.lib ssleay32.lib\r
 ZLIBLIBSDLL= zdll.lib\r
 ZLIBLIBS   = zlib.lib\r
-!IFDEF USEMM_LIBS\r
-WINLIBS    = wsock32.lib wldap32.lib winmm.lib\r
-!ELSE\r
 WINLIBS    = wsock32.lib wldap32.lib\r
-CFLAGS     = $(CFLAGS) /DWITHOUT_MM_LIB\r
-!ENDIF\r
-#  RSAglue.lib was formerly needed in the SSLLIBS\r
+CFLAGS     = $(CFLAGS)\r
+\r
 CFGSET     = FALSE\r
 \r
 !IFDEF WINDOWS_SSPI\r
index 6c0fb411f632002c4ca35876bebbc5b9e760d376..b3f6c74ff6474f1aaa72c2b3183a4613871706ca 100644 (file)
 #define CURL_DISABLE_FILE 1
 #define CURL_DISABLE_TELNET 1
 #define CURL_DISABLE_LDAP 1
-#define WITHOUT_MM_LIB 1
 
 #ifdef HAVE_WINDOWS_H
 #  ifndef WIN32_LEAN_AND_MEAN
index cfc7b5aa8cbd094e06d1965c658bb7b47a86a617..7035980599c89351d2a84df47d1ade9aa67874c5 100644 (file)
@@ -54,7 +54,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo\r
 LINK32=link.exe\r
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386\r
-# ADD LINK32 kernel32.lib ws2_32.lib wldap32.lib winmm.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libcurl.dll"\r
+# ADD LINK32 kernel32.lib ws2_32.lib wldap32.lib /nologo /dll /map /debug /machine:I386 /out:"Release/libcurl.dll"\r
 \r
 !ELSEIF  "$(CFG)" == "curllib - Win32 Debug"\r
 \r
@@ -81,7 +81,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo\r
 LINK32=link.exe\r
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept\r
-# ADD LINK32 kernel32.lib ws2_32.lib wldap32.lib winmm.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libcurl.dll" /pdbtype:sept\r
+# ADD LINK32 kernel32.lib ws2_32.lib wldap32.lib /nologo /dll /incremental:no /map /debug /machine:I386 /out:"Debug/libcurl.dll" /pdbtype:sept\r
 # SUBTRACT LINK32 /nodefaultlib\r
 \r
 !ENDIF \r
index c305bc9fa45177d4700692173fbd596ceb6be1af..847933ee9c4c8e8981059a3820eac7c5813bd404 100644 (file)
@@ -184,7 +184,7 @@ int Curl_socket_ready(curl_socket_t readfd, curl_socket_t writefd,
     return r;
   }
 
-  /* Avoid initial timestamp, avoid gettimeofday() call, when elapsed
+  /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
      time in this function does not need to be measured. This happens
      when function is called with a zero timeout or a negative timeout
      value indicating a blocking call should be performed. */
@@ -368,7 +368,7 @@ int Curl_poll(struct pollfd ufds[], unsigned int nfds, int timeout_ms)
     return r;
   }
 
-  /* Avoid initial timestamp, avoid gettimeofday() call, when elapsed
+  /* Avoid initial timestamp, avoid curlx_tvnow() call, when elapsed
      time in this function does not need to be measured. This happens
      when function is called with a zero timeout or a negative timeout
      value indicating a blocking call should be performed. */
index bb9c0a174d9e73179a2401d19ba7f21ac3ae8d9f..b36633384d654a2f1d259bdebf1ed39056e6e080 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
 
 #include "timeval.h"
 
-#ifndef HAVE_GETTIMEOFDAY
+#if defined(WIN32) && !defined(MSDOS)
 
-#ifdef WIN32
-#include <mmsystem.h>
-
-static int gettimeofday(struct timeval *tp, void *nothing)
+struct timeval curlx_tvnow(void)
 {
-#ifdef WITHOUT_MM_LIB
-  SYSTEMTIME st;
-  time_t tt;
-  struct tm tmtm;
-  /* mktime converts local to UTC */
-  GetLocalTime (&st);
-  tmtm.tm_sec = st.wSecond;
-  tmtm.tm_min = st.wMinute;
-  tmtm.tm_hour = st.wHour;
-  tmtm.tm_mday = st.wDay;
-  tmtm.tm_mon = st.wMonth - 1;
-  tmtm.tm_year = st.wYear - 1900;
-  tmtm.tm_isdst = -1;
-  tt = mktime (&tmtm);
-  tp->tv_sec = tt;
-  tp->tv_usec = st.wMilliseconds * 1000;
-#else
-  /**
-   ** The earlier time calculations using GetLocalTime
-   ** had a time resolution of 10ms.The timeGetTime, part
-   ** of multimedia apis offer a better time resolution
-   ** of 1ms.Need to link against winmm.lib for this
-   **/
-  unsigned long Ticks = 0;
-  unsigned long Sec =0;
-  unsigned long Usec = 0;
-  Ticks = timeGetTime();
-
-  Sec = Ticks/1000;
-  Usec = (Ticks - (Sec*1000))*1000;
-  tp->tv_sec = Sec;
-  tp->tv_usec = Usec;
-#endif /* WITHOUT_MM_LIB */
-  (void)nothing;
-  return 0;
+  /*
+  ** GetTickCount() is available on _all_ Windows versions from W95 up
+  ** to nowadays. Returns milliseconds elapsed since last system boot,
+  ** increases monotonically and wraps once 49.7 days have elapsed.
+  */
+  struct timeval now;
+  DWORD milliseconds = GetTickCount();
+  now.tv_sec = milliseconds / 1000;
+  now.tv_usec = (milliseconds % 1000) * 1000;
+  return now;
 }
-#else /* WIN32 */
-/* non-win32 version of Curl_gettimeofday() */
-static int gettimeofday(struct timeval *tp, void *nothing)
+
+#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+
+struct timeval curlx_tvnow(void)
 {
-  (void)nothing; /* we don't support specific time-zones */
-  tp->tv_sec = (long)time(NULL);
-  tp->tv_usec = 0;
-  return 0;
+  /*
+  ** clock_gettime() is granted to be increased monotonically when the
+  ** monotonic clock is queried. Time starting point is unspecified, it
+  ** could be the system start-up time, the Epoch, or something else,
+  ** in any case the time starting point does not change once that the
+  ** system has started up.
+  */
+  struct timeval now;
+  struct timespec tsnow;
+  (void)clock_gettime(CLOCK_MONOTONIC, &tsnow)
+  now.tv_sec = tsnow.tv_sec;
+  now.tv_usec = tsnow.tv_nsec / 1000;
+  return now;
 }
-#endif /* WIN32 */
-#endif /* HAVE_GETTIMEOFDAY */
 
-/* Return the current time in a timeval struct */
+#elif defined(HAVE_GETTIMEOFDAY)
+
 struct timeval curlx_tvnow(void)
 {
+  /*
+  ** gettimeofday() is not granted to be increased monotonically, due to
+  ** clock drifting and external source time synchronization it can jump
+  ** forward or backward in time.
+  */
   struct timeval now;
   (void)gettimeofday(&now, NULL);
   return now;
 }
 
+#else
+
+struct timeval curlx_tvnow(void)
+{
+  /*
+  ** time() returns the value of time in seconds since the Epoch.
+  */
+  struct timeval now;
+  now.tv_sec = (long)time(NULL);
+  now.tv_usec = 0;
+  return now;
+}
+
+#endif
+
 /*
  * Make sure that the first argument is the more recent time, as otherwise
  * we'll get a weird negative time-diff back...
index 8f75233a670dcbd4641dadc8440eed2c163f767c..942443848cf7a000f2ec817ef5136bad082bc2ce 100644 (file)
@@ -7,7 +7,7 @@
 CC = wcc386
 
 CFLAGS = -3r -mf -d3 -hc -zff -zgf -zq -zm -s -fr=con -w2 -fpi -oilrtfm     &
-         -bt=nt -d+ -dWIN32 -dHAVE_STRTOLL -dWITHOUT_MM_LIB                 &
+         -bt=nt -d+ -dWIN32 -dHAVE_STRTOLL                                  &
          -dSIZEOF_CURL_OFF_T=8 -dCURLDEBUG -dENABLE_IPV6 -dHAVE_WINSOCK2_H  &
          -I..\include -I..\lib
 
index 32817e91593c3db3c7d5319b816bbc88b1b687a6..3ecd999710943d36e204da2ccfda7f4920be507e 100644 (file)
@@ -104,7 +104,7 @@ ifndef USE_LDAP_OPENLDAP
 curl_LDADD += -lwldap32
 endif
 endif
-curl_LDADD += -lws2_32 -lwinmm
+curl_LDADD += -lws2_32
 COMPILE = $(CC) $(INCLUDES) $(CFLAGS)
 
 # Makefile.inc provides the CSOURCES and HHEADERS defines
index 2332422525a6fe8877d19eb86f9152472203f9db..49438d1e381e01b98c60d95de5242ff97bc7e42f 100644 (file)
@@ -10,8 +10,6 @@
 ## Comments to: Troy Engel <tengel@sonic.net>\r
 ## Updated by: Craig Davison <cd@securityfocus.com>\r
 ## release-ssl added by Miklos Nemeth <mnemeth@kfkisystems.com>\r
-## winmm.lib added by Miklos Nemeth <mnemeth@kfkisystems.com> to\r
-## support timeGetTime() in curlutil.c\r
 #\r
 #############################################################\r
 \r
@@ -221,8 +219,8 @@ LFLAGS         = $(LFLAGS) $(SSL_IMP_LFLAGS) $(ZLIB_LFLAGS)
 !ENDIF\r
 \r
 \r
-LINKLIBS       = $(LINKLIBS) wsock32.lib wldap32.lib winmm.lib\r
-LINKLIBS_DEBUG = $(LINKLIBS_DEBUG) wsock32.lib wldap32.lib winmm.lib\r
+LINKLIBS       = $(LINKLIBS) wsock32.lib wldap32.lib\r
+LINKLIBS_DEBUG = $(LINKLIBS_DEBUG) wsock32.lib wldap32.lib\r
 \r
 all : release\r
 \r
index 0394d80e2b68de444948a3867c26b0441e4bb928..12a7d2e06510cb53ea88f5950f948b200e68fea6 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
 
 #include "curlutil.h"
 
-#ifndef HAVE_GETTIMEOFDAY
+#if defined(WIN32) && !defined(MSDOS)
 
-#ifdef WIN32
-#include <mmsystem.h>
-
-static int gettimeofday(struct timeval *tp, void *nothing)
+struct timeval cutil_tvnow(void)
 {
-#ifdef WITHOUT_MM_LIB
-  SYSTEMTIME st;
-  time_t tt;
-  struct tm tmtm;
-  /* mktime converts local to UTC */
-  GetLocalTime (&st);
-  tmtm.tm_sec = st.wSecond;
-  tmtm.tm_min = st.wMinute;
-  tmtm.tm_hour = st.wHour;
-  tmtm.tm_mday = st.wDay;
-  tmtm.tm_mon = st.wMonth - 1;
-  tmtm.tm_year = st.wYear - 1900;
-  tmtm.tm_isdst = -1;
-  tt = mktime (&tmtm);
-  tp->tv_sec = tt;
-  tp->tv_usec = st.wMilliseconds * 1000;
-#else
-  /**
-   ** The earlier time calculations using GetLocalTime
-   ** had a time resolution of 10ms.The timeGetTime, part
-   ** of multimedia apis offer a better time resolution
-   ** of 1ms.Need to link against winmm.lib for this
-   **/
-  unsigned long Ticks = 0;
-  unsigned long Sec =0;
-  unsigned long Usec = 0;
-  Ticks = timeGetTime();
-
-  Sec = Ticks/1000;
-  Usec = (Ticks - (Sec*1000))*1000;
-  tp->tv_sec = Sec;
-  tp->tv_usec = Usec;
-#endif /* WITHOUT_MM_LIB */
-  (void)nothing;
-  return 0;
+  /*
+  ** GetTickCount() is available on _all_ Windows versions from W95 up
+  ** to nowadays. Returns milliseconds elapsed since last system boot,
+  ** increases monotonically and wraps once 49.7 days have elapsed.
+  */
+  struct timeval now;
+  DWORD milliseconds = GetTickCount();
+  now.tv_sec = milliseconds / 1000;
+  now.tv_usec = (milliseconds % 1000) * 1000;
+  return now;
 }
-#else /* WIN32 */
-/* non-win32 version of Curl_gettimeofday() */
-static int gettimeofday(struct timeval *tp, void *nothing)
+
+#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+
+struct timeval cutil_tvnow(void)
 {
-  (void)nothing; /* we don't support specific time-zones */
-  tp->tv_sec = (long)time(NULL);
-  tp->tv_usec = 0;
-  return 0;
+  /*
+  ** clock_gettime() is granted to be increased monotonically when the
+  ** monotonic clock is queried. Time starting point is unspecified, it
+  ** could be the system start-up time, the Epoch, or something else,
+  ** in any case the time starting point does not change once that the
+  ** system has started up.
+  */
+  struct timeval now;
+  struct timespec tsnow;
+  (void)clock_gettime(CLOCK_MONOTONIC, &tsnow)
+  now.tv_sec = tsnow.tv_sec;
+  now.tv_usec = tsnow.tv_nsec / 1000;
+  return now;
 }
-#endif /* WIN32 */
-#endif /* HAVE_GETTIMEOFDAY */
 
-/* Return the current time in a timeval struct */
+#elif defined(HAVE_GETTIMEOFDAY)
+
 struct timeval cutil_tvnow(void)
 {
+  /*
+  ** gettimeofday() is not granted to be increased monotonically, due to
+  ** clock drifting and external source time synchronization it can jump
+  ** forward or backward in time.
+  */
   struct timeval now;
   (void)gettimeofday(&now, NULL);
   return now;
 }
 
+#else
+
+struct timeval cutil_tvnow(void)
+{
+  /*
+  ** time() returns the value of time in seconds since the Epoch.
+  */
+  struct timeval now;
+  now.tv_sec = (long)time(NULL);
+  now.tv_usec = 0;
+  return now;
+}
+
+#endif
+
 /*
  * Make sure that the first argument is the more recent time, as otherwise
  * we'll get a weird negative time-diff back...
index 146660c71342bcd6c216c5738a36d26363f401e5..8ed2b2f08459e653cd542a639109e00a78b2e28d 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
 
 #include "testutil.h"
 
-#ifndef HAVE_GETTIMEOFDAY
+#if defined(WIN32) && !defined(MSDOS)
 
-#ifdef WIN32
-#include <mmsystem.h>
-
-static int gettimeofday(struct timeval *tp, void *nothing)
+struct timeval tutil_tvnow(void)
 {
-#ifdef WITHOUT_MM_LIB
-  SYSTEMTIME st;
-  time_t tt;
-  struct tm tmtm;
-  /* mktime converts local to UTC */
-  GetLocalTime (&st);
-  tmtm.tm_sec = st.wSecond;
-  tmtm.tm_min = st.wMinute;
-  tmtm.tm_hour = st.wHour;
-  tmtm.tm_mday = st.wDay;
-  tmtm.tm_mon = st.wMonth - 1;
-  tmtm.tm_year = st.wYear - 1900;
-  tmtm.tm_isdst = -1;
-  tt = mktime (&tmtm);
-  tp->tv_sec = tt;
-  tp->tv_usec = st.wMilliseconds * 1000;
-#else
-  /**
-   ** The earlier time calculations using GetLocalTime
-   ** had a time resolution of 10ms.The timeGetTime, part
-   ** of multimedia apis offer a better time resolution
-   ** of 1ms.Need to link against winmm.lib for this
-   **/
-  unsigned long Ticks = 0;
-  unsigned long Sec =0;
-  unsigned long Usec = 0;
-  Ticks = timeGetTime();
-
-  Sec = Ticks/1000;
-  Usec = (Ticks - (Sec*1000))*1000;
-  tp->tv_sec = Sec;
-  tp->tv_usec = Usec;
-#endif /* WITHOUT_MM_LIB */
-  (void)nothing;
-  return 0;
+  /*
+  ** GetTickCount() is available on _all_ Windows versions from W95 up
+  ** to nowadays. Returns milliseconds elapsed since last system boot,
+  ** increases monotonically and wraps once 49.7 days have elapsed.
+  */
+  struct timeval now;
+  DWORD milliseconds = GetTickCount();
+  now.tv_sec = milliseconds / 1000;
+  now.tv_usec = (milliseconds % 1000) * 1000;
+  return now;
 }
-#else /* WIN32 */
-/* non-win32 version of Curl_gettimeofday() */
-static int gettimeofday(struct timeval *tp, void *nothing)
+
+#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
+
+struct timeval tutil_tvnow(void)
 {
-  (void)nothing; /* we don't support specific time-zones */
-  tp->tv_sec = (long)time(NULL);
-  tp->tv_usec = 0;
-  return 0;
+  /*
+  ** clock_gettime() is granted to be increased monotonically when the
+  ** monotonic clock is queried. Time starting point is unspecified, it
+  ** could be the system start-up time, the Epoch, or something else,
+  ** in any case the time starting point does not change once that the
+  ** system has started up.
+  */
+  struct timeval now;
+  struct timespec tsnow;
+  (void)clock_gettime(CLOCK_MONOTONIC, &tsnow)
+  now.tv_sec = tsnow.tv_sec;
+  now.tv_usec = tsnow.tv_nsec / 1000;
+  return now;
 }
-#endif /* WIN32 */
-#endif /* HAVE_GETTIMEOFDAY */
 
-/* Return the current time in a timeval struct */
+#elif defined(HAVE_GETTIMEOFDAY)
+
 struct timeval tutil_tvnow(void)
 {
+  /*
+  ** gettimeofday() is not granted to be increased monotonically, due to
+  ** clock drifting and external source time synchronization it can jump
+  ** forward or backward in time.
+  */
   struct timeval now;
   (void)gettimeofday(&now, NULL);
   return now;
 }
 
+#else
+
+struct timeval tutil_tvnow(void)
+{
+  /*
+  ** time() returns the value of time in seconds since the Epoch.
+  */
+  struct timeval now;
+  now.tv_sec = (long)time(NULL);
+  now.tv_usec = 0;
+  return now;
+}
+
+#endif
+
 /*
  * Make sure that the first argument is the more recent time, as otherwise
  * we'll get a weird negative time-diff back...