}
/* Limit the bandwidth by pausing the download for an amount of time.
- BYTES is the number of bytes received from the network, and DELTA
- is the number of milliseconds it took to receive them. */
+ BYTES is the number of bytes received from the network, and TIMER
+ is the timer that started at the beginning of download. */
static void
-limit_bandwidth (long bytes, double *dltime, struct wget_timer *timer)
+limit_bandwidth (long bytes, struct wget_timer *timer)
{
- double delta_t = *dltime - limit_data.chunk_start;
+ double delta_t = wtimer_read (timer) - limit_data.chunk_start;
double expected;
limit_data.chunk_bytes += bytes;
DEBUGP (("\nsleeping %.2f ms for %ld bytes, adjust %.2f ms\n",
slp, limit_data.chunk_bytes, limit_data.sleep_adjust));
- t0 = *dltime;
+ t0 = wtimer_read (timer);
xsleep (slp / 1000);
- t1 = wtimer_elapsed (timer);
+ wtimer_update (timer);
+ t1 = wtimer_read (timer);
/* Due to scheduling, we probably slept slightly longer (or
shorter) than desired. Calculate the difference between the
desired and the actual sleep, and adjust the next sleep by
that amount. */
limit_data.sleep_adjust = slp - (t1 - t0);
-
- /* Since we've called wtimer_elapsed, we might as well update
- the caller's dltime. */
- *dltime = t1;
}
limit_data.chunk_bytes = 0;
- limit_data.chunk_start = *dltime;
+ limit_data.chunk_start = wtimer_read (timer);
}
#define MIN(i, j) ((i) <= (j) ? (i) : (j))
void *progress = NULL;
struct wget_timer *timer = wtimer_allocate ();
- double dltime = 0;
*len = restval;
/* Always flush the contents of the network packet. This should
not hinder performance: fast downloads will be received in
16K chunks (which stdio would write out anyway), and slow
- downloads won't be limited with disk performance. */
+ downloads won't be limited by disk performance. */
fflush (fp);
if (ferror (fp))
{
goto out;
}
- dltime = wtimer_elapsed (timer);
+ wtimer_update (timer);
if (opt.limit_rate)
- limit_bandwidth (res, &dltime, timer);
+ limit_bandwidth (res, timer);
*len += res;
if (progress)
- progress_update (progress, res, dltime);
+ progress_update (progress, res, wtimer_read (timer));
#ifdef WINDOWS
if (use_expected && expected > 0)
ws_percenttitle (100.0 * (double)(*len) / (double)expected);
out:
if (progress)
- progress_finish (progress, dltime);
+ progress_finish (progress, wtimer_read (timer));
if (elapsed)
- *elapsed = dltime;
+ *elapsed = wtimer_read (timer);
wtimer_delete (timer);
return res;
}
/* Reset timer WT. This establishes the starting point from which
- wtimer_elapsed() will return the number of elapsed
- milliseconds. It is allowed to reset a previously used timer. */
+ wtimer_elapsed() will return the number of elapsed milliseconds.
+ It is allowed to reset a previously used timer.
+
+ If a non-zero value is used as START, the timer's values will be
+ offset by START. */
void
wtimer_reset (struct wget_timer *wt)
#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. These timers handle clock
- skew. */
+/* Update the timer's elapsed interval. This function causes the
+ timer to call gettimeofday (or time(), etc.) to update its idea of
+ current time. To get the elapsed interval in milliseconds, use
+ wtimer_read.
-double
-wtimer_elapsed (struct wget_timer *wt)
+ This function handles clock skew, i.e. time that moves backwards is
+ ignored. */
+
+void
+wtimer_update (struct wget_timer *wt)
{
wget_sys_time now;
double elapsed;
}
wt->elapsed_last = elapsed;
- return elapsed;
+}
+
+/* Return the elapsed time in milliseconds between the last call to
+ wtimer_reset and the last call to wtimer_update.
+
+ A typical use of the timer interface would be:
+
+ struct wtimer *timer = wtimer_new ();
+ ... do something that takes a while ...
+ wtimer_update ();
+ double msecs = wtimer_read (); */
+
+double
+wtimer_read (const struct wget_timer *wt)
+{
+ return wt->elapsed_last;
}
/* Return the assessed granularity of the timer implementation, in