dd: speed measurement. optional.

function                                             old     new   delta
dd_output_status                                      68     289    +221
dd_main                                             1463    1482     +19
write_and_stats                                       64      75     +11
packed_usage                                       26529   26526      -3
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 251/-3)            Total: 248 bytes
Signed-off-by: Gabor Heja <kakaopor@kakaopor.hu>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Gabor Heja 2009-10-14 00:29:28 +02:00 committed by Denys Vlasenko
parent d31575a3ae
commit 4e5b07b0fe
2 changed files with 66 additions and 7 deletions

View File

@ -127,7 +127,16 @@ config FEATURE_DD_SIGNAL_HANDLING
$ dd if=/dev/zero of=/dev/null&
$ pid=$! kill -USR1 $pid; sleep 1; kill $pid
10899206+0 records in 10899206+0 records out
10899206+0 records in
10899206+0 records out
config FEATURE_DD_THIRD_STATUS_LINE
bool "Enable the third status line upon signal"
default n
depends on DD && FEATURE_DD_SIGNAL_HANDLING
help
Displays a coreutils-like third status line with transferred bytes,
elapsed time and speed.
config FEATURE_DD_IBS_OBS
bool "Enable ibs, obs and conv options"

View File

@ -34,6 +34,10 @@ static const struct suffix_mult dd_suffixes[] = {
struct globals {
off_t out_full, out_part, in_full, in_part;
#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
unsigned long long total_bytes;
unsigned long long begin_time_us;
#endif
};
#define G (*(struct globals*)&bb_common_bufsiz1)
#define INIT_G() do { \
@ -44,11 +48,50 @@ struct globals {
static void dd_output_status(int UNUSED_PARAM cur_signal)
{
#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
unsigned long long total;
unsigned long long diff_scaled;
unsigned long long diff_us = monotonic_us(); /* before fprintf */
#endif
/* Deliberately using %u, not %d */
fprintf(stderr, "%"OFF_FMT"u+%"OFF_FMT"u records in\n"
"%"OFF_FMT"u+%"OFF_FMT"u records out\n",
G.in_full, G.in_part,
G.out_full, G.out_part);
#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
fprintf(stderr, "%llu bytes (%sB) copied, ",
G.total_bytes,
/* show fractional digit, use suffixes */
make_human_readable_str(G.total_bytes, 1, 0)
);
/* Corner cases:
* ./busybox dd </dev/null >/dev/null
* ./busybox dd bs=1M count=2000 </dev/zero >/dev/null
* (echo DONE) | ./busybox dd >/dev/null
* (sleep 1; echo DONE) | ./busybox dd >/dev/null
*/
diff_us -= G.begin_time_us;
/* We need to calculate "(total * 1M) / usec" without overflow.
* this would work too, but is bigger than integer code below.
* total = G.total_bytes * (double)(1024 * 1024) / (diff_us ? diff_us : 1);
*/
diff_scaled = diff_us;
total = G.total_bytes;
while (total > MAXINT(unsigned long long) / (1024 * 1024)) {
total >>= 1;
diff_scaled >>= 1;
}
total *= (1024 * 1024);
if (diff_scaled > 1)
total /= diff_scaled;
fprintf(stderr, "%f seconds, %sB/s\n",
diff_us / 1000000.0,
/* show fractional digit, use suffixes */
make_human_readable_str(total, 1, 0)
);
#endif
}
static ssize_t full_write_or_warn(const void *buf, size_t len,
@ -70,13 +113,16 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs,
G.out_full++;
else if (n) /* > 0 */
G.out_part++;
#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
G.total_bytes += n;
#endif
return 0;
}
#if ENABLE_LFS
#define XATOU_SFX xatoull_sfx
# define XATOU_SFX xatoull_sfx
#else
#define XATOU_SFX xatoul_sfx
# define XATOU_SFX xatoul_sfx
#endif
int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@ -157,10 +203,6 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
INIT_G();
//fflush(NULL); - is this needed because of NOEXEC?
#if ENABLE_FEATURE_DD_SIGNAL_HANDLING
signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status);
#endif
for (n = 1; argv[n]; n++) {
int what;
char *val;
@ -246,6 +288,14 @@ int dd_main(int argc UNUSED_PARAM, char **argv)
flags |= FLAG_TWOBUFS;
obuf = xmalloc(obs);
}
#if ENABLE_FEATURE_DD_SIGNAL_HANDLING
signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status);
#endif
#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
G.begin_time_us = monotonic_us();
#endif
if (infile != NULL)
xmove_fd(xopen(infile, O_RDONLY), ifd);
else {