diff options
| author | Gabor Heja <kakaopor@kakaopor.hu> | 2009-10-14 00:29:28 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-10-14 00:29:28 +0200 |
| commit | 4e5b07b0fed4be34ab3b22666e2a68e7ec2738d8 (patch) | |
| tree | 0187df507bf015d650e00eeaf30d6ad516fcc54e | |
| parent | d31575a3ae7f3a607c0a5001474d75dc73d422d8 (diff) | |
| download | busybox-w32-4e5b07b0fed4be34ab3b22666e2a68e7ec2738d8.tar.gz busybox-w32-4e5b07b0fed4be34ab3b22666e2a68e7ec2738d8.tar.bz2 busybox-w32-4e5b07b0fed4be34ab3b22666e2a68e7ec2738d8.zip | |
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>
| -rw-r--r-- | coreutils/Config.in | 11 | ||||
| -rw-r--r-- | coreutils/dd.c | 62 |
2 files changed, 66 insertions, 7 deletions
diff --git a/coreutils/Config.in b/coreutils/Config.in index 2d745e260..fa35241f4 100644 --- a/coreutils/Config.in +++ b/coreutils/Config.in | |||
| @@ -127,7 +127,16 @@ config FEATURE_DD_SIGNAL_HANDLING | |||
| 127 | 127 | ||
| 128 | $ dd if=/dev/zero of=/dev/null& | 128 | $ dd if=/dev/zero of=/dev/null& |
| 129 | $ pid=$! kill -USR1 $pid; sleep 1; kill $pid | 129 | $ pid=$! kill -USR1 $pid; sleep 1; kill $pid |
| 130 | 10899206+0 records in 10899206+0 records out | 130 | 10899206+0 records in |
| 131 | 10899206+0 records out | ||
| 132 | |||
| 133 | config FEATURE_DD_THIRD_STATUS_LINE | ||
| 134 | bool "Enable the third status line upon signal" | ||
| 135 | default n | ||
| 136 | depends on DD && FEATURE_DD_SIGNAL_HANDLING | ||
| 137 | help | ||
| 138 | Displays a coreutils-like third status line with transferred bytes, | ||
| 139 | elapsed time and speed. | ||
| 131 | 140 | ||
| 132 | config FEATURE_DD_IBS_OBS | 141 | config FEATURE_DD_IBS_OBS |
| 133 | bool "Enable ibs, obs and conv options" | 142 | bool "Enable ibs, obs and conv options" |
diff --git a/coreutils/dd.c b/coreutils/dd.c index c5c9476af..768a12995 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
| @@ -34,6 +34,10 @@ static const struct suffix_mult dd_suffixes[] = { | |||
| 34 | 34 | ||
| 35 | struct globals { | 35 | struct globals { |
| 36 | off_t out_full, out_part, in_full, in_part; | 36 | off_t out_full, out_part, in_full, in_part; |
| 37 | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE | ||
| 38 | unsigned long long total_bytes; | ||
| 39 | unsigned long long begin_time_us; | ||
| 40 | #endif | ||
| 37 | }; | 41 | }; |
| 38 | #define G (*(struct globals*)&bb_common_bufsiz1) | 42 | #define G (*(struct globals*)&bb_common_bufsiz1) |
| 39 | #define INIT_G() do { \ | 43 | #define INIT_G() do { \ |
| @@ -44,11 +48,50 @@ struct globals { | |||
| 44 | 48 | ||
| 45 | static void dd_output_status(int UNUSED_PARAM cur_signal) | 49 | static void dd_output_status(int UNUSED_PARAM cur_signal) |
| 46 | { | 50 | { |
| 51 | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE | ||
| 52 | unsigned long long total; | ||
| 53 | unsigned long long diff_scaled; | ||
| 54 | unsigned long long diff_us = monotonic_us(); /* before fprintf */ | ||
| 55 | #endif | ||
| 56 | |||
| 47 | /* Deliberately using %u, not %d */ | 57 | /* Deliberately using %u, not %d */ |
| 48 | fprintf(stderr, "%"OFF_FMT"u+%"OFF_FMT"u records in\n" | 58 | fprintf(stderr, "%"OFF_FMT"u+%"OFF_FMT"u records in\n" |
| 49 | "%"OFF_FMT"u+%"OFF_FMT"u records out\n", | 59 | "%"OFF_FMT"u+%"OFF_FMT"u records out\n", |
| 50 | G.in_full, G.in_part, | 60 | G.in_full, G.in_part, |
| 51 | G.out_full, G.out_part); | 61 | G.out_full, G.out_part); |
| 62 | |||
| 63 | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE | ||
| 64 | fprintf(stderr, "%llu bytes (%sB) copied, ", | ||
| 65 | G.total_bytes, | ||
| 66 | /* show fractional digit, use suffixes */ | ||
| 67 | make_human_readable_str(G.total_bytes, 1, 0) | ||
| 68 | ); | ||
| 69 | /* Corner cases: | ||
| 70 | * ./busybox dd </dev/null >/dev/null | ||
| 71 | * ./busybox dd bs=1M count=2000 </dev/zero >/dev/null | ||
| 72 | * (echo DONE) | ./busybox dd >/dev/null | ||
| 73 | * (sleep 1; echo DONE) | ./busybox dd >/dev/null | ||
| 74 | */ | ||
| 75 | diff_us -= G.begin_time_us; | ||
| 76 | /* We need to calculate "(total * 1M) / usec" without overflow. | ||
| 77 | * this would work too, but is bigger than integer code below. | ||
| 78 | * total = G.total_bytes * (double)(1024 * 1024) / (diff_us ? diff_us : 1); | ||
| 79 | */ | ||
| 80 | diff_scaled = diff_us; | ||
| 81 | total = G.total_bytes; | ||
| 82 | while (total > MAXINT(unsigned long long) / (1024 * 1024)) { | ||
| 83 | total >>= 1; | ||
| 84 | diff_scaled >>= 1; | ||
| 85 | } | ||
| 86 | total *= (1024 * 1024); | ||
| 87 | if (diff_scaled > 1) | ||
| 88 | total /= diff_scaled; | ||
| 89 | fprintf(stderr, "%f seconds, %sB/s\n", | ||
| 90 | diff_us / 1000000.0, | ||
| 91 | /* show fractional digit, use suffixes */ | ||
| 92 | make_human_readable_str(total, 1, 0) | ||
| 93 | ); | ||
| 94 | #endif | ||
| 52 | } | 95 | } |
| 53 | 96 | ||
| 54 | static ssize_t full_write_or_warn(const void *buf, size_t len, | 97 | 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, | |||
| 70 | G.out_full++; | 113 | G.out_full++; |
| 71 | else if (n) /* > 0 */ | 114 | else if (n) /* > 0 */ |
| 72 | G.out_part++; | 115 | G.out_part++; |
| 116 | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE | ||
| 117 | G.total_bytes += n; | ||
| 118 | #endif | ||
| 73 | return 0; | 119 | return 0; |
| 74 | } | 120 | } |
| 75 | 121 | ||
| 76 | #if ENABLE_LFS | 122 | #if ENABLE_LFS |
| 77 | #define XATOU_SFX xatoull_sfx | 123 | # define XATOU_SFX xatoull_sfx |
| 78 | #else | 124 | #else |
| 79 | #define XATOU_SFX xatoul_sfx | 125 | # define XATOU_SFX xatoul_sfx |
| 80 | #endif | 126 | #endif |
| 81 | 127 | ||
| 82 | int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 128 | int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| @@ -157,10 +203,6 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
| 157 | INIT_G(); | 203 | INIT_G(); |
| 158 | //fflush(NULL); - is this needed because of NOEXEC? | 204 | //fflush(NULL); - is this needed because of NOEXEC? |
| 159 | 205 | ||
| 160 | #if ENABLE_FEATURE_DD_SIGNAL_HANDLING | ||
| 161 | signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status); | ||
| 162 | #endif | ||
| 163 | |||
| 164 | for (n = 1; argv[n]; n++) { | 206 | for (n = 1; argv[n]; n++) { |
| 165 | int what; | 207 | int what; |
| 166 | char *val; | 208 | char *val; |
| @@ -246,6 +288,14 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
| 246 | flags |= FLAG_TWOBUFS; | 288 | flags |= FLAG_TWOBUFS; |
| 247 | obuf = xmalloc(obs); | 289 | obuf = xmalloc(obs); |
| 248 | } | 290 | } |
| 291 | |||
| 292 | #if ENABLE_FEATURE_DD_SIGNAL_HANDLING | ||
| 293 | signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status); | ||
| 294 | #endif | ||
| 295 | #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE | ||
| 296 | G.begin_time_us = monotonic_us(); | ||
| 297 | #endif | ||
| 298 | |||
| 249 | if (infile != NULL) | 299 | if (infile != NULL) |
| 250 | xmove_fd(xopen(infile, O_RDONLY), ifd); | 300 | xmove_fd(xopen(infile, O_RDONLY), ifd); |
| 251 | else { | 301 | else { |
