mirror of
https://github.com/curl/curl.git
synced 2026-08-25 15:53:39 +03:00
progress: cleanup, less memory
Keep only a single `start` time and calculate the rest in delta microseconds since then. Separate timestamps and durations into separate sub-structures for clarity. remove progress.t_acceptdata It was recorded in FTP accept but never used anywhere. Closes #22547
This commit is contained in:
parent
fbfb2499f0
commit
35843dd635
13 changed files with 144 additions and 141 deletions
110
lib/progress.c
110
lib/progress.c
|
|
@ -188,7 +188,7 @@ const struct curltime *Curl_pgrs_now(struct Curl_easy *data)
|
|||
int Curl_pgrsDone(struct Curl_easy *data)
|
||||
{
|
||||
int rc;
|
||||
data->progress.lastshow = 0;
|
||||
data->progress.delta.lastshow_us = -1;
|
||||
rc = Curl_pgrsUpdate(data); /* the final (forced) update */
|
||||
if(rc)
|
||||
return rc;
|
||||
|
|
@ -247,7 +247,6 @@ static const char * const pgrs_timer_names[] = {
|
|||
"PGRS-PRETRANSFER",
|
||||
"PGRS-STARTTRANSFER",
|
||||
"PGRS-POSTRANSFER",
|
||||
"PGRS-STARTACCEPT",
|
||||
"PGRS-REDIRECT",
|
||||
};
|
||||
|
||||
|
|
@ -274,34 +273,33 @@ void Curl_pgrsTimeWas(struct Curl_easy *data, timerid timer,
|
|||
break;
|
||||
case TIMER_STARTOP:
|
||||
/* This is set at the start of a transfer */
|
||||
data->progress.t_startop = timestamp;
|
||||
data->progress.t_startqueue = timestamp;
|
||||
data->progress.t_postqueue = 0;
|
||||
data->progress.delta.startop_us =
|
||||
curlx_ptimediff_us(×tamp, &data->progress.start);
|
||||
data->progress.delta.startqueue_us = data->progress.delta.startop_us;
|
||||
break;
|
||||
case TIMER_STARTSINGLE:
|
||||
/* This is set at the start of each single transfer */
|
||||
data->progress.t_startsingle = timestamp;
|
||||
data->progress.is_t_startransfer_set = FALSE;
|
||||
data->progress.delta.startsingle_us =
|
||||
curlx_ptimediff_us(×tamp, &data->progress.start);
|
||||
data->progress.startransfer_added = FALSE;
|
||||
break;
|
||||
case TIMER_POSTQUEUE:
|
||||
/* Queue time is accumulative from all involved redirects */
|
||||
data->progress.t_postqueue +=
|
||||
curlx_ptimediff_us(×tamp, &data->progress.t_startqueue);
|
||||
break;
|
||||
case TIMER_STARTACCEPT:
|
||||
data->progress.t_acceptdata = timestamp;
|
||||
data->progress.total.queued_us +=
|
||||
curlx_ptimediff_us(×tamp, &data->progress.start) -
|
||||
data->progress.delta.startqueue_us;
|
||||
break;
|
||||
case TIMER_NAMELOOKUP:
|
||||
delta = &data->progress.t_nslookup;
|
||||
delta = &data->progress.total.nslookup_us;
|
||||
break;
|
||||
case TIMER_CONNECT:
|
||||
delta = &data->progress.t_connect;
|
||||
delta = &data->progress.total.connect_us;
|
||||
break;
|
||||
case TIMER_APPCONNECT:
|
||||
delta = &data->progress.t_appconnect;
|
||||
delta = &data->progress.total.appconnect_us;
|
||||
break;
|
||||
case TIMER_PRETRANSFER:
|
||||
delta = &data->progress.t_pretransfer;
|
||||
delta = &data->progress.total.pretransfer_us;
|
||||
break;
|
||||
case TIMER_STARTTRANSFER:
|
||||
/* prevent updating t_starttransfer unless:
|
||||
|
|
@ -310,25 +308,27 @@ void Curl_pgrsTimeWas(struct Curl_easy *data, timerid timer,
|
|||
* This prevents repeated invocations of the function from incorrectly
|
||||
* changing the t_starttransfer time.
|
||||
*/
|
||||
if(data->progress.is_t_startransfer_set) {
|
||||
if(data->progress.startransfer_added) {
|
||||
CURL_TRC_M(data, "[%s] ignored", pgrs_timer_name(timer));
|
||||
return;
|
||||
}
|
||||
data->progress.is_t_startransfer_set = TRUE;
|
||||
delta = &data->progress.t_starttransfer;
|
||||
data->progress.startransfer_added = TRUE;
|
||||
delta = &data->progress.total.starttransfer_us;
|
||||
break;
|
||||
case TIMER_POSTRANSFER:
|
||||
delta = &data->progress.t_posttransfer;
|
||||
delta = &data->progress.total.posttransfer_us;
|
||||
break;
|
||||
case TIMER_REDIRECT:
|
||||
data->progress.t_redirect = curlx_ptimediff_us(×tamp,
|
||||
&data->progress.start);
|
||||
data->progress.t_startqueue = timestamp;
|
||||
data->progress.delta.startredirect_us =
|
||||
curlx_ptimediff_us(×tamp, &data->progress.start);
|
||||
/* transfer starts queueing again */
|
||||
data->progress.delta.startqueue_us =
|
||||
data->progress.delta.startredirect_us;
|
||||
break;
|
||||
}
|
||||
if(delta) {
|
||||
timediff_t us = curlx_ptimediff_us(×tamp,
|
||||
&data->progress.t_startsingle);
|
||||
timediff_t us = curlx_ptimediff_us(×tamp, &data->progress.start) -
|
||||
data->progress.delta.startsingle_us;
|
||||
if(us < 1)
|
||||
us = 1; /* make sure at least one microsecond passed */
|
||||
*delta += us;
|
||||
|
|
@ -350,13 +350,17 @@ void Curl_pgrsTime(struct Curl_easy *data, timerid timer)
|
|||
Curl_pgrsTimeWas(data, timer, *Curl_pgrs_now(data));
|
||||
}
|
||||
|
||||
void Curl_pgrsStartNow(struct Curl_easy *data)
|
||||
void Curl_pgrsStart(struct Curl_easy *data, const struct curltime *pnow)
|
||||
{
|
||||
struct Progress *p = &data->progress;
|
||||
|
||||
if(!pnow)
|
||||
pnow = Curl_pgrs_now(data);
|
||||
p->speeder_c = 0; /* reset the progress meter display */
|
||||
p->start = *Curl_pgrs_now(data);
|
||||
p->is_t_startransfer_set = FALSE;
|
||||
p->start = *pnow;
|
||||
memset(&p->delta, 0, sizeof(p->delta));
|
||||
memset(&p->total, 0, sizeof(p->total));
|
||||
p->startransfer_added = FALSE;
|
||||
p->dl.cur_size = 0;
|
||||
p->ul.cur_size = 0;
|
||||
/* the sizes are unknown at start */
|
||||
|
|
@ -456,21 +460,22 @@ static bool progress_calc(struct Curl_easy *data,
|
|||
{
|
||||
struct Progress * const p = &data->progress;
|
||||
int i_next, i_oldest, i_latest;
|
||||
timediff_t duration_us;
|
||||
timediff_t duration_us, elapsed_us;
|
||||
curl_off_t amount;
|
||||
|
||||
/* The time spent so far (from the start) in microseconds */
|
||||
p->timespent = curlx_ptimediff_us(pnow, &p->start);
|
||||
p->dl.speed = trspeed(p->dl.cur_size, p->timespent);
|
||||
p->ul.speed = trspeed(p->ul.cur_size, p->timespent);
|
||||
elapsed_us = curlx_ptimediff_us(pnow, &p->start);
|
||||
p->total.spent_us = elapsed_us;
|
||||
p->dl.speed = trspeed(p->dl.cur_size, p->total.spent_us);
|
||||
p->ul.speed = trspeed(p->ul.cur_size, p->total.spent_us);
|
||||
|
||||
if(!p->speeder_c) { /* no previous record exists */
|
||||
p->speed_amount[0] = p->dl.cur_size + p->ul.cur_size;
|
||||
p->speed_time[0] = *pnow;
|
||||
p->speed_time[0] = elapsed_us;
|
||||
p->speeder_c++;
|
||||
/* use the overall average at the start */
|
||||
p->current_speed = p->ul.speed + p->dl.speed;
|
||||
p->lastshow = pnow->tv_sec;
|
||||
p->delta.lastshow_us = elapsed_us;
|
||||
return TRUE;
|
||||
}
|
||||
/* We have at least one record now. Where to put the next and
|
||||
|
|
@ -480,11 +485,11 @@ static bool progress_calc(struct Curl_easy *data,
|
|||
|
||||
/* Make a new record only when some time has passed.
|
||||
* Too frequent calls otherwise ruin the history. */
|
||||
if(curlx_ptimediff_ms(pnow, &p->speed_time[i_latest]) >= 1000) {
|
||||
if((elapsed_us - p->speed_time[i_latest]) >= (1000 * 1000)) {
|
||||
p->speeder_c++;
|
||||
i_latest = i_next;
|
||||
p->speed_amount[i_latest] = p->dl.cur_size + p->ul.cur_size;
|
||||
p->speed_time[i_latest] = *pnow;
|
||||
p->speed_time[i_latest] = elapsed_us;
|
||||
}
|
||||
else if(data->req.done) {
|
||||
/* When a transfer is done, and we did not have a current speed
|
||||
|
|
@ -493,7 +498,7 @@ static bool progress_calc(struct Curl_easy *data,
|
|||
* reported speed since it no longer measures a full second. */
|
||||
if(!p->current_speed) {
|
||||
p->speed_amount[i_latest] = p->dl.cur_size + p->ul.cur_size;
|
||||
p->speed_time[i_latest] = *pnow;
|
||||
p->speed_time[i_latest] = elapsed_us;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -507,8 +512,7 @@ static bool progress_calc(struct Curl_easy *data,
|
|||
/* How much we transferred between oldest and current records */
|
||||
amount = p->speed_amount[i_latest] - p->speed_amount[i_oldest];
|
||||
/* How long this took */
|
||||
duration_us = curlx_ptimediff_us(&p->speed_time[i_latest],
|
||||
&p->speed_time[i_oldest]);
|
||||
duration_us = p->speed_time[i_latest] - p->speed_time[i_oldest];
|
||||
if(duration_us <= 0)
|
||||
duration_us = 1;
|
||||
|
||||
|
|
@ -522,9 +526,10 @@ static bool progress_calc(struct Curl_easy *data,
|
|||
p->current_speed = amount * 1000000 / duration_us;
|
||||
}
|
||||
|
||||
if((p->lastshow == pnow->tv_sec) && !data->req.done)
|
||||
if((p->delta.lastshow_us >= 0) && !data->req.done &&
|
||||
((elapsed_us - p->delta.lastshow_us) >= (1000 * 1000)))
|
||||
return FALSE;
|
||||
p->lastshow = pnow->tv_sec;
|
||||
p->delta.lastshow_us = elapsed_us;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -569,7 +574,7 @@ static void progress_meter(struct Curl_easy *data)
|
|||
char time_left[8];
|
||||
char time_total[8];
|
||||
char time_spent[8];
|
||||
curl_off_t cur_secs = (curl_off_t)p->timespent / 1000000; /* seconds */
|
||||
curl_off_t cur_secs = (curl_off_t)p->total.spent_us / 1000000;
|
||||
|
||||
if(!p->headers_out) {
|
||||
if(data->state.resume_from) {
|
||||
|
|
@ -731,5 +736,24 @@ void Curl_pgrsUpdate_nometer(struct Curl_easy *data)
|
|||
void Curl_pgrsCompleted(struct Curl_easy *data)
|
||||
{
|
||||
struct Progress * const p = &data->progress;
|
||||
p->timespent = curlx_ptimediff_us(Curl_pgrs_now(data), &p->start);
|
||||
p->total.spent_us = curlx_ptimediff_us(Curl_pgrs_now(data), &p->start);
|
||||
}
|
||||
|
||||
timediff_t Curl_pgrs_since_ms(struct Curl_easy *data,
|
||||
const struct curltime *pnow,
|
||||
timerid timer)
|
||||
{
|
||||
if(!pnow)
|
||||
pnow = Curl_pgrs_now(data);
|
||||
switch(timer) {
|
||||
case TIMER_STARTOP:
|
||||
return (curlx_ptimediff_us(pnow, &data->progress.start) -
|
||||
data->progress.delta.startop_us) / 1000;
|
||||
case TIMER_STARTSINGLE:
|
||||
return (curlx_ptimediff_us(pnow, &data->progress.start) -
|
||||
data->progress.delta.startsingle_us) / 1000;
|
||||
default:
|
||||
DEBUGASSERT(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue