diff --git a/lib/getinfo.c b/lib/getinfo.c index a1ce5058e..b94a5359a 100644 --- a/lib/getinfo.c +++ b/lib/getinfo.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -246,27 +246,29 @@ static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info, return CURLE_OK; } +#define DOUBLE_SECS(x) (double)(x)/1000000 + static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info, double *param_doublep) { switch(info) { case CURLINFO_TOTAL_TIME: - *param_doublep = data->progress.timespent; + *param_doublep = DOUBLE_SECS(data->progress.timespent); break; case CURLINFO_NAMELOOKUP_TIME: - *param_doublep = data->progress.t_nslookup; + *param_doublep = DOUBLE_SECS(data->progress.t_nslookup); break; case CURLINFO_CONNECT_TIME: - *param_doublep = data->progress.t_connect; + *param_doublep = DOUBLE_SECS(data->progress.t_connect); break; case CURLINFO_APPCONNECT_TIME: - *param_doublep = data->progress.t_appconnect; + *param_doublep = DOUBLE_SECS(data->progress.t_appconnect); break; case CURLINFO_PRETRANSFER_TIME: - *param_doublep = data->progress.t_pretransfer; + *param_doublep = DOUBLE_SECS(data->progress.t_pretransfer); break; case CURLINFO_STARTTRANSFER_TIME: - *param_doublep = data->progress.t_starttransfer; + *param_doublep = DOUBLE_SECS(data->progress.t_starttransfer); break; case CURLINFO_SIZE_UPLOAD: *param_doublep = (double)data->progress.uploaded; @@ -289,7 +291,7 @@ static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info, (double)data->progress.size_ul:-1; break; case CURLINFO_REDIRECT_TIME: - *param_doublep = data->progress.t_redirect; + *param_doublep = DOUBLE_SECS(data->progress.t_redirect); break; default: diff --git a/lib/progress.c b/lib/progress.c index cfaf4049e..1996d78dc 100644 --- a/lib/progress.c +++ b/lib/progress.c @@ -152,10 +152,10 @@ int Curl_pgrsDone(struct connectdata *conn) /* reset all times except redirect, and reset the known transfer sizes */ void Curl_pgrsResetTimesSizes(struct Curl_easy *data) { - data->progress.t_nslookup = 0.0; - data->progress.t_connect = 0.0; - data->progress.t_pretransfer = 0.0; - data->progress.t_starttransfer = 0.0; + data->progress.t_nslookup = 0; + data->progress.t_connect = 0; + data->progress.t_pretransfer = 0; + data->progress.t_starttransfer = 0; Curl_pgrsSetDownloadSize(data, -1); Curl_pgrsSetUploadSize(data, -1); @@ -164,6 +164,7 @@ void Curl_pgrsResetTimesSizes(struct Curl_easy *data) void Curl_pgrsTime(struct Curl_easy *data, timerid timer) { struct timeval now = Curl_tvnow(); + time_t *delta = NULL; switch(timer) { default: @@ -178,38 +179,37 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer) /* This is set at the start of each single fetch */ data->progress.t_startsingle = now; break; - case TIMER_STARTACCEPT: - data->progress.t_acceptdata = Curl_tvnow(); + data->progress.t_acceptdata = now; break; - case TIMER_NAMELOOKUP: - data->progress.t_nslookup = - Curl_tvdiff_secs(now, data->progress.t_startsingle); + delta = &data->progress.t_nslookup; break; case TIMER_CONNECT: - data->progress.t_connect = - Curl_tvdiff_secs(now, data->progress.t_startsingle); + delta = &data->progress.t_connect; break; case TIMER_APPCONNECT: - data->progress.t_appconnect = - Curl_tvdiff_secs(now, data->progress.t_startsingle); + delta = &data->progress.t_appconnect; break; case TIMER_PRETRANSFER: - data->progress.t_pretransfer = - Curl_tvdiff_secs(now, data->progress.t_startsingle); + delta = &data->progress.t_pretransfer; break; case TIMER_STARTTRANSFER: - data->progress.t_starttransfer = - Curl_tvdiff_secs(now, data->progress.t_startsingle); + delta = &data->progress.t_starttransfer; break; case TIMER_POSTRANSFER: /* this is the normal end-of-transfer thing */ break; case TIMER_REDIRECT: - data->progress.t_redirect = Curl_tvdiff_secs(now, data->progress.start); + data->progress.t_redirect = Curl_tvdiff_us(now, data->progress.start); break; } + if(delta) { + time_t us = Curl_tvdiff_us(now, data->progress.t_startsingle); + if(!us) + us++; /* make sure at least one microsecond passed */ + *delta = us; + } } void Curl_pgrsStartNow(struct Curl_easy *data) @@ -361,17 +361,17 @@ int Curl_pgrsUpdate(struct connectdata *conn) now = Curl_tvnow(); /* what time is it */ /* The time spent so far (from the start) */ - data->progress.timespent = curlx_tvdiff_secs(now, data->progress.start); + data->progress.timespent = Curl_tvdiff_us(now, data->progress.start); timespent = (curl_off_t)data->progress.timespent; /* The average download speed this far */ data->progress.dlspeed = (curl_off_t) - ((double)data->progress.downloaded/ + (data->progress.downloaded/ (data->progress.timespent>0?data->progress.timespent:1)); /* The average upload speed this far */ data->progress.ulspeed = (curl_off_t) - ((double)data->progress.uploaded/ + (data->progress.uploaded/ (data->progress.timespent>0?data->progress.timespent:1)); /* Calculations done at most once a second, unless end is reached */ diff --git a/lib/timeval.c b/lib/timeval.c index bed44c573..1012b4e39 100644 --- a/lib/timeval.c +++ b/lib/timeval.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -130,14 +130,24 @@ time_t curlx_tvdiff(struct timeval newer, struct timeval older) } /* - * Same as curlx_tvdiff but with full usec resolution. + * Make sure that the first argument is the more recent time, as otherwise + * we'll get a weird negative time-diff back... * - * Returns: the time difference in seconds with subsecond resolution. + * Returns: the time difference in number of microseconds. For too large diffs + * it returns max value. */ -double curlx_tvdiff_secs(struct timeval newer, struct timeval older) +time_t Curl_tvdiff_us(struct timeval newer, struct timeval older) { - if(newer.tv_sec != older.tv_sec) - return (double)(newer.tv_sec-older.tv_sec)+ - (double)(newer.tv_usec-older.tv_usec)/1000000.0; - return (double)(newer.tv_usec-older.tv_usec)/1000000.0; + time_t diff = newer.tv_sec-older.tv_sec; +#if SIZEOF_TIME_T < 8 + /* for 32bit time_t systems */ + if(diff >= (0x7fffffff/1000000)) + return 0x7fffffff; +#else + /* for 64bit time_t systems */ + if(diff >= (0x7fffffffffffffff/1000000)) + return 0x7fffffffffffffff; +#endif + return (newer.tv_sec-older.tv_sec)*1000000+ + (time_t)(newer.tv_usec-older.tv_usec); } diff --git a/lib/timeval.h b/lib/timeval.h index 33969354d..9217018a8 100644 --- a/lib/timeval.h +++ b/lib/timeval.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -40,17 +40,17 @@ struct timeval curlx_tvnow(void); time_t curlx_tvdiff(struct timeval t1, struct timeval t2); /* - * Same as curlx_tvdiff but with full usec resolution. + * Make sure that the first argument (t1) is the more recent time and t2 is + * the older time, as otherwise you get a weird negative time-diff back... * - * Returns: the time difference in seconds with subsecond resolution. + * Returns: the time difference in number of microseconds. */ -double curlx_tvdiff_secs(struct timeval t1, struct timeval t2); +time_t Curl_tvdiff_us(struct timeval newer, struct timeval older); /* These two defines below exist to provide the older API for library internals only. */ #define Curl_tvnow() curlx_tvnow() #define Curl_tvdiff(x,y) curlx_tvdiff(x,y) -#define Curl_tvdiff_secs(x,y) curlx_tvdiff_secs(x,y) #endif /* HEADER_CURL_TIMEVAL_H */ diff --git a/lib/urldata.h b/lib/urldata.h index d4a4a98dc..2d0f46a17 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1213,17 +1213,17 @@ struct Progress { int width; /* screen width at download start */ int flags; /* see progress.h */ - double timespent; + time_t timespent; curl_off_t dlspeed; curl_off_t ulspeed; - double t_nslookup; - double t_connect; - double t_appconnect; - double t_pretransfer; - double t_starttransfer; - double t_redirect; + time_t t_nslookup; + time_t t_connect; + time_t t_appconnect; + time_t t_pretransfer; + time_t t_starttransfer; + time_t t_redirect; struct timeval start; struct timeval t_startsingle;