Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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>
  • Loading branch information...
commit 53ed7b5a5d7a0ad2ffafd4a4ba4a7861f5db624e 1 parent ec640ed
Nicolas Pitre authored gitster committed

Showing 1 changed file with 39 additions and 25 deletions. Show diff stats Hide diff stats

  1. +39 25 progress.c
64 progress.c
@@ -14,11 +14,12 @@
14 14 #define TP_IDX_MAX 8
15 15
16 16 struct throughput {
  17 + off_t curr_total;
17 18 off_t prev_total;
18 19 struct timeval prev_tv;
19 20 unsigned int avg_bytes;
20   - unsigned int last_bytes[TP_IDX_MAX];
21 21 unsigned int avg_misecs;
  22 + unsigned int last_bytes[TP_IDX_MAX];
22 23 unsigned int last_misecs[TP_IDX_MAX];
23 24 unsigned int idx;
24 25 char display[32];
@@ -109,6 +110,30 @@ static int display(struct progress *progress, unsigned n, int done)
109 110 return 0;
110 111 }
111 112
  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 +
112 137 void display_throughput(struct progress *progress, off_t total)
113 138 {
114 139 struct throughput *tp;
@@ -124,11 +149,12 @@ void display_throughput(struct progress *progress, off_t total)
124 149 if (!tp) {
125 150 progress->throughput = tp = calloc(1, sizeof(*tp));
126 151 if (tp) {
127   - tp->prev_total = total;
  152 + tp->prev_total = tp->curr_total = total;
128 153 tp->prev_tv = tv;
129 154 }
130 155 return;
131 156 }
  157 + tp->curr_total = total;
132 158
133 159 /*
134 160 * 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)
149 175 misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;
150 176
151 177 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;
154 181 tp->prev_total = total;
155 182 tp->prev_tv = tv;
156 183 tp->avg_bytes += count;
157 184 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;
179 186 tp->avg_bytes -= tp->last_bytes[tp->idx];
180 187 tp->avg_misecs -= tp->last_misecs[tp->idx];
181 188 tp->last_bytes[tp->idx] = count;
182 189 tp->last_misecs[tp->idx] = misecs;
183 190 tp->idx = (tp->idx + 1) % TP_IDX_MAX;
184 191
  192 + throughput_string(tp, total, rate);
185 193 if (progress->last_value != -1 && progress_update)
186 194 display(progress, progress->last_value, 0);
187 195 }
@@ -225,6 +233,12 @@ void stop_progress(struct progress **p_progress)
225 233 *p_progress = NULL;
226 234 if (progress->last_value != -1) {
227 235 /* 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 + }
228 242 progress_update = 1;
229 243 display(progress, progress->last_value, 1);
230 244 }

0 comments on commit 53ed7b5

Please sign in to comment.
Something went wrong with that request. Please try again.