1414#define TP_IDX_MAX 8
1515
1616struct 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+
112137void 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