aboutsummaryrefslogtreecommitdiff
path: root/coreutils/dd.c
diff options
context:
space:
mode:
authorGabor Heja <kakaopor@kakaopor.hu>2009-10-14 00:29:28 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-10-14 00:29:28 +0200
commit4e5b07b0fed4be34ab3b22666e2a68e7ec2738d8 (patch)
tree0187df507bf015d650e00eeaf30d6ad516fcc54e /coreutils/dd.c
parentd31575a3ae7f3a607c0a5001474d75dc73d422d8 (diff)
downloadbusybox-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>
Diffstat (limited to 'coreutils/dd.c')
-rw-r--r--coreutils/dd.c62
1 files changed, 56 insertions, 6 deletions
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
35struct globals { 35struct 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
45static void dd_output_status(int UNUSED_PARAM cur_signal) 49static 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
54static ssize_t full_write_or_warn(const void *buf, size_t len, 97static 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
82int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 128int 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 {