mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 08:08:50 -05:00
timers: store internal time stamps as time_t instead of doubles
This gives us accurate precision and it allows us to avoid storing "no time" for systems with too low timer resolution as we then bump the time up to 1 microsecond. Should fix test 573 on windows. Remove the now unused curlx_tvdiff_secs() function. Maintains the external getinfo() API with using doubles. Fixes #1531
This commit is contained in:
parent
11c2fb0446
commit
adef394ac5
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DOUBLE_SECS(x) (double)(x)/1000000
|
||||||
|
|
||||||
static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
|
static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
|
||||||
double *param_doublep)
|
double *param_doublep)
|
||||||
{
|
{
|
||||||
switch(info) {
|
switch(info) {
|
||||||
case CURLINFO_TOTAL_TIME:
|
case CURLINFO_TOTAL_TIME:
|
||||||
*param_doublep = data->progress.timespent;
|
*param_doublep = DOUBLE_SECS(data->progress.timespent);
|
||||||
break;
|
break;
|
||||||
case CURLINFO_NAMELOOKUP_TIME:
|
case CURLINFO_NAMELOOKUP_TIME:
|
||||||
*param_doublep = data->progress.t_nslookup;
|
*param_doublep = DOUBLE_SECS(data->progress.t_nslookup);
|
||||||
break;
|
break;
|
||||||
case CURLINFO_CONNECT_TIME:
|
case CURLINFO_CONNECT_TIME:
|
||||||
*param_doublep = data->progress.t_connect;
|
*param_doublep = DOUBLE_SECS(data->progress.t_connect);
|
||||||
break;
|
break;
|
||||||
case CURLINFO_APPCONNECT_TIME:
|
case CURLINFO_APPCONNECT_TIME:
|
||||||
*param_doublep = data->progress.t_appconnect;
|
*param_doublep = DOUBLE_SECS(data->progress.t_appconnect);
|
||||||
break;
|
break;
|
||||||
case CURLINFO_PRETRANSFER_TIME:
|
case CURLINFO_PRETRANSFER_TIME:
|
||||||
*param_doublep = data->progress.t_pretransfer;
|
*param_doublep = DOUBLE_SECS(data->progress.t_pretransfer);
|
||||||
break;
|
break;
|
||||||
case CURLINFO_STARTTRANSFER_TIME:
|
case CURLINFO_STARTTRANSFER_TIME:
|
||||||
*param_doublep = data->progress.t_starttransfer;
|
*param_doublep = DOUBLE_SECS(data->progress.t_starttransfer);
|
||||||
break;
|
break;
|
||||||
case CURLINFO_SIZE_UPLOAD:
|
case CURLINFO_SIZE_UPLOAD:
|
||||||
*param_doublep = (double)data->progress.uploaded;
|
*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;
|
(double)data->progress.size_ul:-1;
|
||||||
break;
|
break;
|
||||||
case CURLINFO_REDIRECT_TIME:
|
case CURLINFO_REDIRECT_TIME:
|
||||||
*param_doublep = data->progress.t_redirect;
|
*param_doublep = DOUBLE_SECS(data->progress.t_redirect);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -152,10 +152,10 @@ int Curl_pgrsDone(struct connectdata *conn)
|
|||||||
/* reset all times except redirect, and reset the known transfer sizes */
|
/* reset all times except redirect, and reset the known transfer sizes */
|
||||||
void Curl_pgrsResetTimesSizes(struct Curl_easy *data)
|
void Curl_pgrsResetTimesSizes(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
data->progress.t_nslookup = 0.0;
|
data->progress.t_nslookup = 0;
|
||||||
data->progress.t_connect = 0.0;
|
data->progress.t_connect = 0;
|
||||||
data->progress.t_pretransfer = 0.0;
|
data->progress.t_pretransfer = 0;
|
||||||
data->progress.t_starttransfer = 0.0;
|
data->progress.t_starttransfer = 0;
|
||||||
|
|
||||||
Curl_pgrsSetDownloadSize(data, -1);
|
Curl_pgrsSetDownloadSize(data, -1);
|
||||||
Curl_pgrsSetUploadSize(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)
|
void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
|
||||||
{
|
{
|
||||||
struct timeval now = Curl_tvnow();
|
struct timeval now = Curl_tvnow();
|
||||||
|
time_t *delta = NULL;
|
||||||
|
|
||||||
switch(timer) {
|
switch(timer) {
|
||||||
default:
|
default:
|
||||||
@ -178,38 +179,37 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
|
|||||||
/* This is set at the start of each single fetch */
|
/* This is set at the start of each single fetch */
|
||||||
data->progress.t_startsingle = now;
|
data->progress.t_startsingle = now;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIMER_STARTACCEPT:
|
case TIMER_STARTACCEPT:
|
||||||
data->progress.t_acceptdata = Curl_tvnow();
|
data->progress.t_acceptdata = now;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TIMER_NAMELOOKUP:
|
case TIMER_NAMELOOKUP:
|
||||||
data->progress.t_nslookup =
|
delta = &data->progress.t_nslookup;
|
||||||
Curl_tvdiff_secs(now, data->progress.t_startsingle);
|
|
||||||
break;
|
break;
|
||||||
case TIMER_CONNECT:
|
case TIMER_CONNECT:
|
||||||
data->progress.t_connect =
|
delta = &data->progress.t_connect;
|
||||||
Curl_tvdiff_secs(now, data->progress.t_startsingle);
|
|
||||||
break;
|
break;
|
||||||
case TIMER_APPCONNECT:
|
case TIMER_APPCONNECT:
|
||||||
data->progress.t_appconnect =
|
delta = &data->progress.t_appconnect;
|
||||||
Curl_tvdiff_secs(now, data->progress.t_startsingle);
|
|
||||||
break;
|
break;
|
||||||
case TIMER_PRETRANSFER:
|
case TIMER_PRETRANSFER:
|
||||||
data->progress.t_pretransfer =
|
delta = &data->progress.t_pretransfer;
|
||||||
Curl_tvdiff_secs(now, data->progress.t_startsingle);
|
|
||||||
break;
|
break;
|
||||||
case TIMER_STARTTRANSFER:
|
case TIMER_STARTTRANSFER:
|
||||||
data->progress.t_starttransfer =
|
delta = &data->progress.t_starttransfer;
|
||||||
Curl_tvdiff_secs(now, data->progress.t_startsingle);
|
|
||||||
break;
|
break;
|
||||||
case TIMER_POSTRANSFER:
|
case TIMER_POSTRANSFER:
|
||||||
/* this is the normal end-of-transfer thing */
|
/* this is the normal end-of-transfer thing */
|
||||||
break;
|
break;
|
||||||
case TIMER_REDIRECT:
|
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;
|
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)
|
void Curl_pgrsStartNow(struct Curl_easy *data)
|
||||||
@ -361,17 +361,17 @@ int Curl_pgrsUpdate(struct connectdata *conn)
|
|||||||
now = Curl_tvnow(); /* what time is it */
|
now = Curl_tvnow(); /* what time is it */
|
||||||
|
|
||||||
/* The time spent so far (from the start) */
|
/* 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;
|
timespent = (curl_off_t)data->progress.timespent;
|
||||||
|
|
||||||
/* The average download speed this far */
|
/* The average download speed this far */
|
||||||
data->progress.dlspeed = (curl_off_t)
|
data->progress.dlspeed = (curl_off_t)
|
||||||
((double)data->progress.downloaded/
|
(data->progress.downloaded/
|
||||||
(data->progress.timespent>0?data->progress.timespent:1));
|
(data->progress.timespent>0?data->progress.timespent:1));
|
||||||
|
|
||||||
/* The average upload speed this far */
|
/* The average upload speed this far */
|
||||||
data->progress.ulspeed = (curl_off_t)
|
data->progress.ulspeed = (curl_off_t)
|
||||||
((double)data->progress.uploaded/
|
(data->progress.uploaded/
|
||||||
(data->progress.timespent>0?data->progress.timespent:1));
|
(data->progress.timespent>0?data->progress.timespent:1));
|
||||||
|
|
||||||
/* Calculations done at most once a second, unless end is reached */
|
/* Calculations done at most once a second, unless end is reached */
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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)
|
time_t diff = newer.tv_sec-older.tv_sec;
|
||||||
return (double)(newer.tv_sec-older.tv_sec)+
|
#if SIZEOF_TIME_T < 8
|
||||||
(double)(newer.tv_usec-older.tv_usec)/1000000.0;
|
/* for 32bit time_t systems */
|
||||||
return (double)(newer.tv_usec-older.tv_usec)/1000000.0;
|
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);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* This software is licensed as described in the file COPYING, which
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* 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);
|
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
|
/* These two defines below exist to provide the older API for library
|
||||||
internals only. */
|
internals only. */
|
||||||
#define Curl_tvnow() curlx_tvnow()
|
#define Curl_tvnow() curlx_tvnow()
|
||||||
#define Curl_tvdiff(x,y) curlx_tvdiff(x,y)
|
#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 */
|
#endif /* HEADER_CURL_TIMEVAL_H */
|
||||||
|
|
||||||
|
@ -1213,17 +1213,17 @@ struct Progress {
|
|||||||
int width; /* screen width at download start */
|
int width; /* screen width at download start */
|
||||||
int flags; /* see progress.h */
|
int flags; /* see progress.h */
|
||||||
|
|
||||||
double timespent;
|
time_t timespent;
|
||||||
|
|
||||||
curl_off_t dlspeed;
|
curl_off_t dlspeed;
|
||||||
curl_off_t ulspeed;
|
curl_off_t ulspeed;
|
||||||
|
|
||||||
double t_nslookup;
|
time_t t_nslookup;
|
||||||
double t_connect;
|
time_t t_connect;
|
||||||
double t_appconnect;
|
time_t t_appconnect;
|
||||||
double t_pretransfer;
|
time_t t_pretransfer;
|
||||||
double t_starttransfer;
|
time_t t_starttransfer;
|
||||||
double t_redirect;
|
time_t t_redirect;
|
||||||
|
|
||||||
struct timeval start;
|
struct timeval start;
|
||||||
struct timeval t_startsingle;
|
struct timeval t_startsingle;
|
||||||
|
Loading…
Reference in New Issue
Block a user