diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-07 17:47:39 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-02-07 17:47:39 +0100 |
commit | ab843e3244e98f92e16b9c9c1f06dbab87e97175 (patch) | |
tree | c534b6d979ce22b71970b87ab3f6a725793aac25 | |
parent | 2bd5b4e9a0442102ab937ed771b2c11142afb744 (diff) | |
download | busybox-w32-ab843e3244e98f92e16b9c9c1f06dbab87e97175.tar.gz busybox-w32-ab843e3244e98f92e16b9c9c1f06dbab87e97175.tar.bz2 busybox-w32-ab843e3244e98f92e16b9c9c1f06dbab87e97175.zip |
libbb: shrink wget/tftp progress indicator code for 32-bit
function old new delta
bb_progress_update 756 654 -102
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | libbb/progress.c | 78 |
1 files changed, 38 insertions, 40 deletions
diff --git a/libbb/progress.c b/libbb/progress.c index 64e6529ac..17272fd17 100644 --- a/libbb/progress.c +++ b/libbb/progress.c | |||
@@ -71,7 +71,7 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
71 | uoff_t transferred, | 71 | uoff_t transferred, |
72 | uoff_t totalsize) | 72 | uoff_t totalsize) |
73 | { | 73 | { |
74 | uoff_t beg_and_transferred; | 74 | unsigned beg_and_transferred; /* does not need uoff_t, see scaling code below */ |
75 | unsigned since_last_update, elapsed; | 75 | unsigned since_last_update, elapsed; |
76 | int notty; | 76 | int notty; |
77 | int kiloscale; | 77 | int kiloscale; |
@@ -102,33 +102,24 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
102 | * without risking overflow: we guarantee 10 highest bits to be 0. | 102 | * without risking overflow: we guarantee 10 highest bits to be 0. |
103 | * Introduced error is less than 1 / 2^12 ~= 0.025% | 103 | * Introduced error is less than 1 / 2^12 ~= 0.025% |
104 | */ | 104 | */ |
105 | if (ULONG_MAX > 0xffffffff || sizeof(off_t) == 4 || sizeof(off_t) != 8) { | 105 | while (totalsize >= (1 << 22)) { |
106 | /* | 106 | totalsize >>= 10; |
107 | * 64-bit CPU || small off_t: in either case, | 107 | beg_size >>= 10; |
108 | * >> is cheap, single-word operation. | 108 | transferred >>= 10; |
109 | * ... || strange off_t: also use this code | 109 | kiloscale++; |
110 | * (it is safe, just suboptimal wrt code size), | ||
111 | * because 32/64 optimized one works only for 64-bit off_t. | ||
112 | */ | ||
113 | if (totalsize >= (1 << 22)) { | ||
114 | totalsize >>= 10; | ||
115 | beg_size >>= 10; | ||
116 | transferred >>= 10; | ||
117 | kiloscale = 1; | ||
118 | } | ||
119 | } else { | ||
120 | /* 32-bit CPU and 64-bit off_t. | ||
121 | * Use a 40-bit shift, it is easier to do on 32-bit CPU. | ||
122 | */ | ||
123 | /* ONE suppresses "warning: shift count >= width of type" */ | ||
124 | #define ONE (sizeof(off_t) > 4) | ||
125 | if (totalsize >= (uoff_t)(1ULL << 54*ONE)) { | ||
126 | totalsize = (uint32_t)(totalsize >> 32*ONE) >> 8; | ||
127 | beg_size = (uint32_t)(beg_size >> 32*ONE) >> 8; | ||
128 | transferred = (uint32_t)(transferred >> 32*ONE) >> 8; | ||
129 | kiloscale = 4; | ||
130 | } | ||
131 | } | 110 | } |
111 | /* If they were huge, now they are scaled down to [4194303,4096] range. | ||
112 | * (N * totalsize) won't overflow 32 bits for N up to 1024. | ||
113 | * The downside is that files larger than 4194303 kbytes (>4GB) | ||
114 | * never show kbytes download size, they show "0M","1M"... right away | ||
115 | * since kiloscale is already >1. | ||
116 | */ | ||
117 | #if ULONG_MAX == 0xffffffff | ||
118 | /* 32-bit CPU, uoff_t arithmetic is complex on it, cast variables to narrower types */ | ||
119 | # define totalsize ((unsigned)totalsize) | ||
120 | # define beg_size ((unsigned)beg_size) | ||
121 | # define transferred ((unsigned)transferred) | ||
122 | #endif | ||
132 | 123 | ||
133 | notty = !isatty(STDERR_FILENO); | 124 | notty = !isatty(STDERR_FILENO); |
134 | 125 | ||
@@ -146,13 +137,18 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
146 | 137 | ||
147 | barlength = get_terminal_width(2) - 49; | 138 | barlength = get_terminal_width(2) - 49; |
148 | if (barlength > 0) { | 139 | if (barlength > 0) { |
149 | /* god bless gcc for variable arrays :) */ | 140 | if (barlength > 999) |
150 | char buf[barlength + 1]; | 141 | barlength = 999; |
151 | unsigned stars = (unsigned)barlength * beg_and_transferred / totalsize; | 142 | { |
152 | memset(buf, ' ', barlength); | 143 | /* god bless gcc for variable arrays :) */ |
153 | buf[barlength] = '\0'; | 144 | char buf[barlength + 1]; |
154 | memset(buf, '*', stars); | 145 | unsigned stars = (unsigned)barlength * beg_and_transferred / totalsize; |
155 | fprintf(stderr, " |%s|", buf); | 146 | /* can't overflow ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ |
147 | memset(buf, ' ', barlength); | ||
148 | buf[barlength] = '\0'; | ||
149 | memset(buf, '*', stars); | ||
150 | fprintf(stderr, " |%s|", buf); | ||
151 | } | ||
156 | } | 152 | } |
157 | } | 153 | } |
158 | 154 | ||
@@ -184,16 +180,18 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, | |||
184 | fprintf(stderr, " --:--:-- ETA"); | 180 | fprintf(stderr, " --:--:-- ETA"); |
185 | } else { | 181 | } else { |
186 | unsigned eta, secs, hours; | 182 | unsigned eta, secs, hours; |
183 | unsigned bytes; | ||
187 | 184 | ||
188 | totalsize -= beg_size; /* now it's "total to upload" */ | 185 | bytes = totalsize - beg_size; |
189 | 186 | ||
190 | /* Estimated remaining time = | 187 | /* Estimated remaining time = |
191 | * estimated_sec_to_dl_totalsize_bytes - elapsed_sec = | 188 | * estimated_sec_to_dl_bytes - elapsed_sec = |
192 | * totalsize / average_bytes_sec_so_far - elapsed = | 189 | * bytes / average_bytes_sec_so_far - elapsed = |
193 | * totalsize / (transferred/elapsed) - elapsed = | 190 | * bytes / (transferred/elapsed) - elapsed = |
194 | * totalsize * elapsed / transferred - elapsed | 191 | * bytes * elapsed / transferred - elapsed |
195 | */ | 192 | */ |
196 | eta = totalsize * elapsed / transferred - elapsed; | 193 | eta = (unsigned long)bytes * elapsed / transferred - elapsed; |
194 | /* if 32bit, can overflow ^^^^^^^^^^, but this would only show bad ETA */ | ||
197 | if (eta >= 1000*60*60) | 195 | if (eta >= 1000*60*60) |
198 | eta = 1000*60*60 - 1; | 196 | eta = 1000*60*60 - 1; |
199 | secs = eta % 3600; | 197 | secs = eta % 3600; |