mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] New timer functions. Published in <sxs8zkp28vk.fsf@florida.arsdigita.de>.
This commit is contained in:
parent
5674776cad
commit
45eea7387f
@ -1,3 +1,26 @@
|
||||
2001-04-25 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||
|
||||
* utils.c: Document timer functions.
|
||||
|
||||
* retr.c (rate): Use it.
|
||||
(rate): Print in GB/s if transfer rate exceeds 1 GB/s.
|
||||
|
||||
* utils.c (wtimer_granularity): New function.
|
||||
|
||||
2001-04-24 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||
|
||||
* retr.c (show_progress): Ditto.
|
||||
|
||||
* ftp.c (getftp): Ditto.
|
||||
|
||||
* http.c (gethttp): Use new timer functions.
|
||||
|
||||
* utils.c (wtimer_allocate): New function.
|
||||
(wtimer_new): Ditto.
|
||||
(wtimer_delete): Ditto.
|
||||
(wtimer_reset): Ditto.
|
||||
(wtimer_elapsed): Ditto.
|
||||
|
||||
2001-04-24 Hrvoje Niksic <hniksic@arsdigita.com>
|
||||
|
||||
* utils.c (long_to_string): New, faster version. Favors smaller
|
||||
|
@ -114,6 +114,7 @@ getftp (struct urlinfo *u, long *len, long restval, ccon *con)
|
||||
FILE *fp;
|
||||
char *user, *passwd, *respline;
|
||||
char *tms, *tmrate;
|
||||
struct wget_timer *timer;
|
||||
unsigned char pasv_addr[6];
|
||||
int cmd = con->cmd;
|
||||
int passive_mode_open = 0;
|
||||
@ -870,10 +871,11 @@ Error in server response, closing control connection.\n"));
|
||||
legible (expected_bytes - restval));
|
||||
logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
|
||||
}
|
||||
reset_timer ();
|
||||
timer = wtimer_new ();
|
||||
/* Get the contents of the document. */
|
||||
res = get_contents (dtsock, fp, len, restval, expected_bytes, &con->rbuf, 0);
|
||||
con->dltime = elapsed_time ();
|
||||
con->dltime = wtimer_elapsed (timer);
|
||||
wtimer_delete (timer);
|
||||
tms = time_str (NULL);
|
||||
tmrate = rate (*len - restval, con->dltime, 0);
|
||||
/* Close data connection socket. */
|
||||
|
@ -526,6 +526,7 @@ gethttp (struct urlinfo *u, struct http_stat *hs, int *dt)
|
||||
static SSL_CTX *ssl_ctx = NULL;
|
||||
SSL *ssl = NULL;
|
||||
#endif /* HAVE_SSL */
|
||||
struct wget_timer *timer;
|
||||
char *cookies = NULL;
|
||||
|
||||
/* Whether this connection will be kept alive after the HTTP request
|
||||
@ -1333,12 +1334,13 @@ Accept: %s\r\n\
|
||||
should be some overhead information. */
|
||||
if (opt.save_headers)
|
||||
fwrite (all_headers, 1, all_length, fp);
|
||||
reset_timer ();
|
||||
timer = wtimer_new ();
|
||||
/* Get the contents of the document. */
|
||||
hs->res = get_contents (sock, fp, &hs->len, hs->restval,
|
||||
(contlen != -1 ? contlen : 0),
|
||||
&rbuf, keep_alive);
|
||||
hs->dltime = elapsed_time ();
|
||||
hs->dltime = wtimer_elapsed (timer);
|
||||
wtimer_delete (timer);
|
||||
{
|
||||
/* Close or flush the file. We have to be careful to check for
|
||||
error here. Checking the result of fwrite() is not enough --
|
||||
|
94
src/retr.c
94
src/retr.c
@ -47,13 +47,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS
|
||||
LARGE_INTEGER internal_time;
|
||||
#else
|
||||
/* Internal variables used by the timer. */
|
||||
static long internal_secs, internal_msecs;
|
||||
#endif
|
||||
|
||||
/* See the comment in gethttp() why this is needed. */
|
||||
int global_download_count;
|
||||
|
||||
@ -175,10 +168,11 @@ print_percentage (long bytes, long expected)
|
||||
static int
|
||||
show_progress (long res, long expected, enum spflags flags)
|
||||
{
|
||||
static struct wget_timer *timer;
|
||||
static long line_bytes;
|
||||
static long offs, initial_skip;
|
||||
static int ndot, nrow;
|
||||
static long last_timer, time_offset;
|
||||
static long last_timer_value, time_offset;
|
||||
int any_output = 0;
|
||||
|
||||
if (flags == SP_FINISH)
|
||||
@ -186,7 +180,7 @@ show_progress (long res, long expected, enum spflags flags)
|
||||
int dot = ndot;
|
||||
char *tmpstr = (char *)alloca (2 * opt.dots_in_line + 1);
|
||||
char *tmpp = tmpstr;
|
||||
time_offset = elapsed_time () - last_timer;
|
||||
time_offset = wtimer_elapsed (timer) - last_timer_value;
|
||||
for (; dot < opt.dots_in_line; dot++)
|
||||
{
|
||||
if (!(dot % opt.dot_spacing))
|
||||
@ -217,7 +211,10 @@ show_progress (long res, long expected, enum spflags flags)
|
||||
offs = 0L;
|
||||
ndot = nrow = 0;
|
||||
line_bytes = (long)opt.dots_in_line * opt.dot_bytes;
|
||||
last_timer = elapsed_time ();
|
||||
if (!timer)
|
||||
timer = wtimer_allocate ();
|
||||
wtimer_reset (timer);
|
||||
last_timer_value = 0;
|
||||
time_offset = 0;
|
||||
initial_skip = res;
|
||||
if (res)
|
||||
@ -247,8 +244,8 @@ show_progress (long res, long expected, enum spflags flags)
|
||||
++ndot;
|
||||
if (ndot == opt.dots_in_line)
|
||||
{
|
||||
time_offset = elapsed_time () - last_timer;
|
||||
last_timer += time_offset;
|
||||
time_offset = wtimer_elapsed (timer) - last_timer_value;
|
||||
last_timer_value += time_offset;
|
||||
|
||||
ndot = 0;
|
||||
++nrow;
|
||||
@ -264,66 +261,11 @@ show_progress (long res, long expected, enum spflags flags)
|
||||
/* Reenable flushing. */
|
||||
opt.no_flush = 0;
|
||||
if (any_output)
|
||||
/* Force flush. #### Oh, what a kludge! */
|
||||
/* Force flush. */
|
||||
logflush ();
|
||||
return any_output;
|
||||
}
|
||||
|
||||
/* Reset the internal timer. */
|
||||
void
|
||||
reset_timer (void)
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
/* Under Unix, the preferred way to measure the passage of time is
|
||||
through gettimeofday() because of its granularity. However, on
|
||||
some old or weird systems, gettimeofday() might not be available.
|
||||
There we use the simple time(). */
|
||||
# ifdef HAVE_GETTIMEOFDAY
|
||||
struct timeval t;
|
||||
gettimeofday (&t, NULL);
|
||||
internal_secs = t.tv_sec;
|
||||
internal_msecs = t.tv_usec / 1000;
|
||||
# else /* not HAVE_GETTIMEOFDAY */
|
||||
internal_secs = time (NULL);
|
||||
internal_msecs = 0;
|
||||
# endif /* not HAVE_GETTIMEOFDAY */
|
||||
#else /* WINDOWS */
|
||||
/* Under Windows, use Windows-specific APIs. */
|
||||
FILETIME ft;
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st,&ft);
|
||||
internal_time.HighPart = ft.dwHighDateTime;
|
||||
internal_time.LowPart = ft.dwLowDateTime;
|
||||
#endif /* WINDOWS */
|
||||
}
|
||||
|
||||
/* Return the time elapsed from the last call to reset_timer(), in
|
||||
milliseconds. */
|
||||
long
|
||||
elapsed_time (void)
|
||||
{
|
||||
#ifndef WINDOWS
|
||||
# ifdef HAVE_GETTIMEOFDAY
|
||||
struct timeval t;
|
||||
gettimeofday (&t, NULL);
|
||||
return ((t.tv_sec - internal_secs) * 1000
|
||||
+ (t.tv_usec / 1000 - internal_msecs));
|
||||
# else /* not HAVE_GETTIMEOFDAY */
|
||||
return 1000 * ((long)time (NULL) - internal_secs);
|
||||
# endif /* not HAVE_GETTIMEOFDAY */
|
||||
#else /* WINDOWS */
|
||||
FILETIME ft;
|
||||
SYSTEMTIME st;
|
||||
LARGE_INTEGER li;
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st,&ft);
|
||||
li.HighPart = ft.dwHighDateTime;
|
||||
li.LowPart = ft.dwLowDateTime;
|
||||
return (long) ((li.QuadPart - internal_time.QuadPart) / 1e4);
|
||||
#endif /* WINDOWS */
|
||||
}
|
||||
|
||||
/* Print out the appropriate download rate. Appropriate means that if
|
||||
rate is > 1024 bytes per second, kilobytes are used, and if rate >
|
||||
1024 * 1024 bps, megabytes are used.
|
||||
@ -336,15 +278,25 @@ rate (long bytes, long msecs, int pad)
|
||||
static char res[15];
|
||||
double dlrate;
|
||||
|
||||
if (!msecs)
|
||||
++msecs;
|
||||
if (msecs == 0)
|
||||
/* If elapsed time is 0, it means we're under the granularity of
|
||||
the timer. This often happens on systems that use time() for
|
||||
the timer. */
|
||||
msecs = wtimer_granularity ();
|
||||
|
||||
dlrate = (double)1000 * bytes / msecs;
|
||||
if (dlrate < 1024.0)
|
||||
sprintf (res, pad ? "%7.2f B/s" : "%.2f B/s", dlrate);
|
||||
else if (dlrate < 1024.0 * 1024.0)
|
||||
sprintf (res, pad ? "%7.2f KB/s" : "%.2f KB/s", dlrate / 1024.0);
|
||||
else
|
||||
else if (dlrate < 1024.0 * 1024.0 * 1024.0)
|
||||
sprintf (res, pad ? "%7.2f MB/s" : "%.2f MB/s", dlrate / (1024.0 * 1024.0));
|
||||
else
|
||||
/* Maybe someone will need this one day. More realistically, it
|
||||
will get tickled by buggy timers. */
|
||||
sprintf (res, pad ? "%7.2f GB/s" : "%.2f GB/s",
|
||||
dlrate / (1024.0 * 1024.0 * 1024.0));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,7 @@ uerr_t retrieve_url PARAMS ((const char *, char **, char **,
|
||||
const char *, int *));
|
||||
uerr_t retrieve_from_file PARAMS ((const char *, int, int *));
|
||||
|
||||
void reset_timer PARAMS ((void));
|
||||
long elapsed_time PARAMS ((void));
|
||||
char *rate PARAMS ((long, long, int));
|
||||
|
||||
void printwhat PARAMS ((int, int));
|
||||
|
||||
void downloaded_increase PARAMS ((unsigned long));
|
||||
|
154
src/utils.c
154
src/utils.c
@ -1532,6 +1532,160 @@ long_to_string (char *buffer, long number)
|
||||
#undef DIGITS_18
|
||||
#undef DIGITS_19
|
||||
|
||||
/* Support for timers. */
|
||||
|
||||
#undef TIMER_WINDOWS
|
||||
#undef TIMER_GETTIMEOFDAY
|
||||
#undef TIMER_TIME
|
||||
|
||||
/* Depending on the OS and availability of gettimeofday(), one and
|
||||
only one of the above constants will be defined. Virtually all
|
||||
modern Unix systems will define TIMER_GETTIMEOFDAY; Windows will
|
||||
use TIMER_WINDOWS. TIMER_TIME is a catch-all method for
|
||||
non-Windows systems without gettimeofday.
|
||||
|
||||
#### Perhaps we should also support ftime(), which exists on old
|
||||
BSD 4.2-influenced systems? (It also existed under MS DOS Borland
|
||||
C, if memory serves me.) */
|
||||
|
||||
#ifdef WINDOWS
|
||||
# define TIMER_WINDOWS
|
||||
#else /* not WINDOWS */
|
||||
# ifdef HAVE_GETTIMEOFDAY
|
||||
# define TIMER_GETTIMEOFDAY
|
||||
# else
|
||||
# define TIMER_TIME
|
||||
# endif
|
||||
#endif /* not WINDOWS */
|
||||
|
||||
struct wget_timer {
|
||||
#ifdef TIMER_GETTIMEOFDAY
|
||||
long secs;
|
||||
long usecs;
|
||||
#endif
|
||||
|
||||
#ifdef TIMER_TIME
|
||||
time_t secs;
|
||||
#endif
|
||||
|
||||
#ifdef TIMER_WINDOWS
|
||||
ULARGE_INTEGER wintime;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Allocate a timer. It is not legal to do anything with a freshly
|
||||
allocated timer, except call wtimer_reset(). */
|
||||
|
||||
struct wget_timer *
|
||||
wtimer_allocate (void)
|
||||
{
|
||||
struct wget_timer *wt =
|
||||
(struct wget_timer *)xmalloc (sizeof (struct wget_timer));
|
||||
return wt;
|
||||
}
|
||||
|
||||
/* Allocate a new timer and reset it. Return the new timer. */
|
||||
|
||||
struct wget_timer *
|
||||
wtimer_new (void)
|
||||
{
|
||||
struct wget_timer *wt = wtimer_allocate ();
|
||||
wtimer_reset (wt);
|
||||
return wt;
|
||||
}
|
||||
|
||||
/* Free the resources associated with the timer. Its further use is
|
||||
prohibited. */
|
||||
|
||||
void
|
||||
wtimer_delete (struct wget_timer *wt)
|
||||
{
|
||||
xfree (wt);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
void
|
||||
wtimer_reset (struct wget_timer *wt)
|
||||
{
|
||||
#ifdef TIMER_GETTIMEOFDAY
|
||||
struct timeval t;
|
||||
gettimeofday (&t, NULL);
|
||||
wt->secs = t.tv_sec;
|
||||
wt->usecs = t.tv_usec;
|
||||
#endif
|
||||
|
||||
#ifdef TIMER_TIME
|
||||
wt->secs = time (NULL);
|
||||
#endif
|
||||
|
||||
#ifdef TIMER_WINDOWS
|
||||
FILETIME ft;
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime (&st);
|
||||
SystemTimeToFileTime (&st, &ft);
|
||||
wt->wintime.HighPart = ft.dwHighDateTime;
|
||||
wt->wintime.LowPart = ft.dwLowDateTime;
|
||||
#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. */
|
||||
|
||||
long
|
||||
wtimer_elapsed (struct wget_timer *wt)
|
||||
{
|
||||
#ifdef TIMER_GETTIMEOFDAY
|
||||
struct timeval t;
|
||||
gettimeofday (&t, NULL);
|
||||
return (t.tv_sec - wt->secs) * 1000 + (t.tv_usec - wt->usecs) / 1000;
|
||||
#endif
|
||||
|
||||
#ifdef TIMER_TIME
|
||||
time_t now = time (NULL);
|
||||
return 1000 * (now - wt->secs);
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS
|
||||
FILETIME ft;
|
||||
SYSTEMTIME st;
|
||||
ULARGE_INTEGER uli;
|
||||
GetSystemTime (&st);
|
||||
SystemTimeToFileTime (&st, &ft);
|
||||
uli.HighPart = ft.dwHighDateTime;
|
||||
uli.LowPart = ft.dwLowDateTime;
|
||||
return (long)((uli.QuadPart - wt->wintime.QuadPart) / 10000);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the assessed granularity of the timer implementation. This
|
||||
is important for certain code that tries to deal with "zero" time
|
||||
intervals. */
|
||||
|
||||
long
|
||||
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;
|
||||
#endif
|
||||
|
||||
#ifdef TIMER_TIME
|
||||
/* This is clear. */
|
||||
return 1000;
|
||||
#endif
|
||||
|
||||
#ifdef TIMER_WINDOWS
|
||||
/* ? */
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This should probably be at a better place, but it doesn't really
|
||||
fit into html-parse.c. */
|
||||
|
||||
|
@ -39,6 +39,8 @@ struct file_memory {
|
||||
int mmap_p;
|
||||
};
|
||||
|
||||
struct wget_timer;
|
||||
|
||||
char *time_str PARAMS ((time_t *));
|
||||
char *datetime_str PARAMS ((time_t *));
|
||||
|
||||
@ -88,6 +90,13 @@ char *legible_very_long PARAMS ((VERY_LONG_TYPE));
|
||||
int numdigit PARAMS ((long));
|
||||
void long_to_string PARAMS ((char *, long));
|
||||
|
||||
struct wget_timer *wtimer_allocate PARAMS ((void));
|
||||
struct wget_timer *wtimer_new PARAMS ((void));
|
||||
void wtimer_delete PARAMS ((struct wget_timer *));
|
||||
void wtimer_reset PARAMS ((struct wget_timer *));
|
||||
long wtimer_elapsed PARAMS ((struct wget_timer *));
|
||||
long wtimer_granularity PARAMS ((void));
|
||||
|
||||
char *html_quote_string PARAMS ((const char *));
|
||||
|
||||
#endif /* UTILS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user