]> sjero.net Git - wget/blobdiff - src/utils.c
[svn] Update progress code to use higher timer resolution.
[wget] / src / utils.c
index a67ec8de09514b1ec73d6a73288715609ef9c1e2..74e4552fd4eeb5c67e58085a3e741a24ea42267f 100644 (file)
@@ -1551,11 +1551,11 @@ struct wget_timer {
 
   /* The most recent elapsed time, calculated by wtimer_elapsed().
      Measured in milliseconds.  */
-  long elapsed_last;
+  double elapsed_last;
 
   /* Approximately, the time elapsed between the true start of the
      measurement and the time represented by START.  */
-  long elapsed_pre_start;
+  double elapsed_pre_start;
 };
 
 /* Allocate a timer.  It is not legal to do anything with a freshly
@@ -1602,9 +1602,20 @@ wtimer_sys_set (wget_sys_time *wst)
 #endif
 
 #ifdef TIMER_WINDOWS
+  /* We use GetSystemTime to get the elapsed time.  MSDN warns that
+     system clock adjustments can skew the output of GetSystemTime
+     when used as a timer and gives preference to GetTickCount and
+     high-resolution timers.  But GetTickCount can overflow, and hires
+     timers are typically used for profiling, not for regular time
+     measurement.  Since we handle clock skew anyway, we just use
+     GetSystemTime.  */
   FILETIME ft;
   SYSTEMTIME st;
   GetSystemTime (&st);
+
+  /* As recommended by MSDN, we convert SYSTEMTIME to FILETIME, copy
+     FILETIME to ULARGE_INTEGER, and use regular 64-bit integer
+     arithmetic on that.  */
   SystemTimeToFileTime (&st, &ft);
   wst->HighPart = ft.dwHighDateTime;
   wst->LowPart  = ft.dwLowDateTime;
@@ -1624,12 +1635,12 @@ wtimer_reset (struct wget_timer *wt)
   wt->elapsed_pre_start = 0;
 }
 
-static long
+static double
 wtimer_sys_diff (wget_sys_time *wst1, wget_sys_time *wst2)
 {
 #ifdef TIMER_GETTIMEOFDAY
-  return ((wst1->tv_sec - wst2->tv_sec) * 1000
-         + (wst1->tv_usec - wst2->tv_usec) / 1000);
+  return ((double)(wst1->tv_sec - wst2->tv_sec) * 1000
+         + (double)(wst1->tv_usec - wst2->tv_usec) / 1000);
 #endif
 
 #ifdef TIMER_TIME
@@ -1637,19 +1648,20 @@ wtimer_sys_diff (wget_sys_time *wst1, wget_sys_time *wst2)
 #endif
 
 #ifdef WINDOWS
-  return (long)(wst1->QuadPart - wst2->QuadPart) / 10000;
+  return (double)(wst1->QuadPart - wst2->QuadPart) / 10000;
 #endif
 }
 
 /* Return the number of milliseconds elapsed since the timer was last
    reset.  It is allowed to call this function more than once to get
-   increasingly higher elapsed values.  */
+   increasingly higher elapsed values.  These timers handle clock
+   skew.  */
 
-long
+double
 wtimer_elapsed (struct wget_timer *wt)
 {
   wget_sys_time now;
-  long elapsed;
+  double elapsed;
 
   wtimer_sys_set (&now);
   elapsed = wt->elapsed_pre_start + wtimer_sys_diff (&now, &wt->start);
@@ -1678,18 +1690,19 @@ wtimer_elapsed (struct wget_timer *wt)
   return elapsed;
 }
 
-/* Return the assessed granularity of the timer implementation.  This
-   is important for certain code that tries to deal with "zero" time
-   intervals.  */
+/* Return the assessed granularity of the timer implementation, in
+   milliseconds.  This is used by code that tries to substitute a
+   better value for timers that have returned zero.  */
 
-long
+double
 wtimer_granularity (void)
 {
 #ifdef TIMER_GETTIMEOFDAY
-  /* Granularity of gettimeofday is hugely architecture-dependent.
-     However, it appears that on modern machines it is better than
-     1ms.  */
-  return 1;
+  /* Granularity of gettimeofday varies wildly between architectures.
+     However, it appears that on modern machines it tends to be better
+     than 1ms.  Assume 100 usecs.  (Perhaps the configure process
+     could actually measure this?)  */
+  return 0.1;
 #endif
 
 #ifdef TIMER_TIME
@@ -1698,7 +1711,8 @@ wtimer_granularity (void)
 #endif
 
 #ifdef TIMER_WINDOWS
-  /* ? */
+  /* According to MSDN, GetSystemTime returns a broken-down time
+     structure the smallest member of which are milliseconds.  */
   return 1;
 #endif
 }