Skip to content

Commit 53ed7b5

Browse files
Nicolas Pitregitster
authored andcommitted
make display of total transferred fully accurate
The minimum delay of 1/2 sec between successive throughput updates might not have been elapsed when display_throughput() is called for the last time, potentially making the display of total transferred bytes not right when progress is said to be done. Let's force an update of the throughput display as well when the progress is complete. As a side effect, the total transferred will always be displayed even if the actual transfer rate doesn't have time to kickin. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent ec640ed commit 53ed7b5

File tree

1 file changed

+39
-25
lines changed

1 file changed

+39
-25
lines changed

progress.c

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
#define TP_IDX_MAX 8
1515

1616
struct throughput {
17+
off_t curr_total;
1718
off_t prev_total;
1819
struct timeval prev_tv;
1920
unsigned int avg_bytes;
20-
unsigned int last_bytes[TP_IDX_MAX];
2121
unsigned int avg_misecs;
22+
unsigned int last_bytes[TP_IDX_MAX];
2223
unsigned int last_misecs[TP_IDX_MAX];
2324
unsigned int idx;
2425
char display[32];
@@ -109,6 +110,30 @@ static int display(struct progress *progress, unsigned n, int done)
109110
return 0;
110111
}
111112

113+
static void throughput_string(struct throughput *tp, off_t total,
114+
unsigned int rate)
115+
{
116+
int l = sizeof(tp->display);
117+
if (total > 1 << 30) {
118+
l -= snprintf(tp->display, l, ", %u.%2.2u GiB",
119+
(int)(total >> 30),
120+
(int)(total & ((1 << 30) - 1)) / 10737419);
121+
} else if (total > 1 << 20) {
122+
l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
123+
(int)(total >> 20),
124+
((int)(total & ((1 << 20) - 1)) * 100) >> 20);
125+
} else if (total > 1 << 10) {
126+
l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
127+
(int)(total >> 10),
128+
((int)(total & ((1 << 10) - 1)) * 100) >> 10);
129+
} else {
130+
l -= snprintf(tp->display, l, ", %u bytes", (int)total);
131+
}
132+
if (rate)
133+
snprintf(tp->display + sizeof(tp->display) - l, l,
134+
" | %u KiB/s", rate);
135+
}
136+
112137
void display_throughput(struct progress *progress, off_t total)
113138
{
114139
struct throughput *tp;
@@ -124,11 +149,12 @@ void display_throughput(struct progress *progress, off_t total)
124149
if (!tp) {
125150
progress->throughput = tp = calloc(1, sizeof(*tp));
126151
if (tp) {
127-
tp->prev_total = total;
152+
tp->prev_total = tp->curr_total = total;
128153
tp->prev_tv = tv;
129154
}
130155
return;
131156
}
157+
tp->curr_total = total;
132158

133159
/*
134160
* We have x = bytes and y = microsecs. We want z = KiB/s:
@@ -149,39 +175,21 @@ void display_throughput(struct progress *progress, off_t total)
149175
misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;
150176

151177
if (misecs > 512) {
152-
int l = sizeof(tp->display);
153-
unsigned int count = total - tp->prev_total;
178+
unsigned int count, rate;
179+
180+
count = total - tp->prev_total;
154181
tp->prev_total = total;
155182
tp->prev_tv = tv;
156183
tp->avg_bytes += count;
157184
tp->avg_misecs += misecs;
158-
159-
if (total > 1 << 30) {
160-
l -= snprintf(tp->display, l, ", %u.%2.2u GiB",
161-
(int)(total >> 30),
162-
(int)(total & ((1 << 30) - 1)) / 10737419);
163-
} else if (total > 1 << 20) {
164-
l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
165-
(int)(total >> 20),
166-
((int)(total & ((1 << 20) - 1))
167-
* 100) >> 20);
168-
} else if (total > 1 << 10) {
169-
l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
170-
(int)(total >> 10),
171-
((int)(total & ((1 << 10) - 1))
172-
* 100) >> 10);
173-
} else {
174-
l -= snprintf(tp->display, l, ", %u bytes", (int)total);
175-
}
176-
snprintf(tp->display + sizeof(tp->display) - l, l,
177-
" | %u KiB/s", tp->avg_bytes / tp->avg_misecs);
178-
185+
rate = tp->avg_bytes / tp->avg_misecs;
179186
tp->avg_bytes -= tp->last_bytes[tp->idx];
180187
tp->avg_misecs -= tp->last_misecs[tp->idx];
181188
tp->last_bytes[tp->idx] = count;
182189
tp->last_misecs[tp->idx] = misecs;
183190
tp->idx = (tp->idx + 1) % TP_IDX_MAX;
184191

192+
throughput_string(tp, total, rate);
185193
if (progress->last_value != -1 && progress_update)
186194
display(progress, progress->last_value, 0);
187195
}
@@ -225,6 +233,12 @@ void stop_progress(struct progress **p_progress)
225233
*p_progress = NULL;
226234
if (progress->last_value != -1) {
227235
/* Force the last update */
236+
struct throughput *tp = progress->throughput;
237+
if (tp) {
238+
unsigned int rate = !tp->avg_misecs ? 0 :
239+
tp->avg_bytes / tp->avg_misecs;
240+
throughput_string(tp, tp->curr_total, rate);
241+
}
228242
progress_update = 1;
229243
display(progress, progress->last_value, 1);
230244
}

0 commit comments

Comments
 (0)