提交 cf84d51c 编写于 作者: N Nicolas Pitre 提交者: Junio C Hamano

add throughput to progress display

This adds the ability for the progress code to also display transfer
throughput when that makes sense.

The math was inspired by commit c548cf4e
from Linus.
Signed-off-by: NNicolas Pitre <nico@cam.org>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 4d4fcc54
#include "git-compat-util.h"
#include "progress.h"
#define TP_IDX_MAX 8
struct throughput {
struct timeval prev_tv;
unsigned long count;
unsigned long avg_bytes;
unsigned long last_bytes[TP_IDX_MAX];
unsigned int avg_misecs;
unsigned int last_misecs[TP_IDX_MAX];
unsigned int idx;
char display[20];
};
struct progress {
const char *title;
int last_value;
......@@ -8,6 +21,7 @@ struct progress {
unsigned last_percent;
unsigned delay;
unsigned delayed_percent_treshold;
struct throughput *throughput;
};
static volatile sig_atomic_t progress_update;
......@@ -46,7 +60,7 @@ static void clear_progress_signal(void)
static int display(struct progress *progress, unsigned n, int done)
{
char *eol;
char *eol, *tp;
if (progress->delay) {
if (!progress_update || --progress->delay)
......@@ -64,18 +78,20 @@ static int display(struct progress *progress, unsigned n, int done)
}
progress->last_value = n;
tp = (progress->throughput) ? progress->throughput->display : "";
eol = done ? ", done. \n" : " \r";
if (progress->total) {
unsigned percent = n * 100 / progress->total;
if (percent != progress->last_percent || progress_update) {
progress->last_percent = percent;
fprintf(stderr, "%s: %3u%% (%u/%u)%s", progress->title,
percent, n, progress->total, eol);
fprintf(stderr, "%s: %3u%% (%u/%u)%s%s",
progress->title, percent, n,
progress->total, tp, eol);
progress_update = 0;
return 1;
}
} else if (progress_update) {
fprintf(stderr, "%s: %u%s", progress->title, n, eol);
fprintf(stderr, "%s: %u%s%s", progress->title, n, tp, eol);
progress_update = 0;
return 1;
}
......@@ -83,6 +99,60 @@ static int display(struct progress *progress, unsigned n, int done)
return 0;
}
void display_throughput(struct progress *progress, unsigned long n)
{
struct throughput *tp;
struct timeval tv;
unsigned int misecs;
if (!progress)
return;
tp = progress->throughput;
gettimeofday(&tv, NULL);
if (!tp) {
progress->throughput = tp = calloc(1, sizeof(*tp));
if (tp)
tp->prev_tv = tv;
return;
}
tp->count += n;
/*
* We have x = bytes and y = microsecs. We want z = KiB/s:
*
* z = (x / 1024) / (y / 1000000)
* z = x / y * 1000000 / 1024
* z = x / (y * 1024 / 1000000)
* z = x / y'
*
* To simplify things we'll keep track of misecs, or 1024th of a sec
* obtained with:
*
* y' = y * 1024 / 1000000
* y' = y / (1000000 / 1024)
* y' = y / 977
*/
misecs = (tv.tv_sec - tp->prev_tv.tv_sec) * 1024;
misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;
if (misecs > 512) {
tp->prev_tv = tv;
tp->avg_bytes += tp->count;
tp->avg_misecs += misecs;
snprintf(tp->display, sizeof(tp->display),
", %lu KiB/s", tp->avg_bytes / tp->avg_misecs);
tp->avg_bytes -= tp->last_bytes[tp->idx];
tp->avg_misecs -= tp->last_misecs[tp->idx];
tp->last_bytes[tp->idx] = tp->count;
tp->last_misecs[tp->idx] = misecs;
tp->idx = (tp->idx + 1) % TP_IDX_MAX;
tp->count = 0;
}
}
int display_progress(struct progress *progress, unsigned n)
{
return progress ? display(progress, n, 0) : 0;
......@@ -103,6 +173,7 @@ struct progress *start_progress_delay(const char *title, unsigned total,
progress->last_percent = -1;
progress->delayed_percent_treshold = percent_treshold;
progress->delay = delay;
progress->throughput = NULL;
set_progress_signal();
return progress;
}
......@@ -124,5 +195,6 @@ void stop_progress(struct progress **p_progress)
display(progress, progress->last_value, 1);
}
clear_progress_signal();
free(progress->throughput);
free(progress);
}
......@@ -3,6 +3,7 @@
struct progress;
void display_throughput(struct progress *progress, unsigned long n);
int display_progress(struct progress *progress, unsigned n);
struct progress *start_progress(const char *title, unsigned total);
struct progress *start_progress_delay(const char *title, unsigned total,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册