Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: common/cmd_time.c

Issue 6670118: Add time measurement command to u-boot (Closed) Base URL: ssh://gitrw.chromium.org:9222/u-boot-next.git@chromeos-v2010.09
Patch Set: Code review Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « common/Makefile ('k') | include/config_cmd_all.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 *
6 * Alternatively, this software may be distributed under the terms of the
7 * GNU General Public License ("GPL") version 2 as published by the Free
8 * Software Foundation.
9 */
10
11 /* time - run a command and report its run time */
12
13 #include <common.h>
14 #include <command.h>
15
16 #define ABSDIFF(u, v) ({ \
17 const unsigned long int __u = (u), __v = (v); \
18 __u > __v ? __u - __v : __v - __u; \
19 })
20
21 static void report_time(unsigned long int cycles)
22 {
23 #ifdef CONFIG_SYS_HZ
24 unsigned long int minutes, seconds, milliseconds;
25 unsigned long int total_seconds, remainder, guess, err, err2;
26
27 total_seconds = cycles / CONFIG_SYS_HZ;
28 minutes = total_seconds / 60;
29 seconds = total_seconds % 60;
30
31 /*
32 * We could approximate millisecond value through
33 * milliseconds = rounding(1000.0 * remainder / CONFIG_SYS_HZ)
34 * where
35 * remainder = cycles % CONFIG_SYS_HZ,
36 * which minimizes the error
37 * fabs(((float) remainder) / CONFIG_SYS_HZ - milliseconds / 1000.0).
38 *
39 * Nevertheless, this approximation, though precise, is undesirable
40 * for its use of floating-point arithmetic.
41 *
42 * So instead we approximate the millisecond value through a 2-step
43 * method that only uses integer arithmetic.
44 *
45 * First, we compute an initial guess
46 * guess = remainder * 1000 / CONFIG_SYS_HZ.
47 *
48 * Then, we adjust the initial guess to form a better guess by
49 * trying guess - 1 and guess + 1.
50 *
51 * My experiment showed that in most cases this 2-step approximation
52 * is as good as the floating-point approximation method above.
53 *
54 * Note: We compute the error using
55 * abs(remainder * 1000 - milliseconds * CONFIG_SYS_HZ)
56 * to avoid divisions (and truncation errors).
57 */
58
59 /* initial guess */
60 remainder = cycles % CONFIG_SYS_HZ;
61 milliseconds = guess = remainder * 1000 / CONFIG_SYS_HZ;
sjg 2011/04/05 01:21:44 I think it is good enough if you just stop here. D
Che-Liang Chiou 2011/04/06 08:48:40 Thanks. This is better.
62 err = ABSDIFF(remainder * 1000, guess * CONFIG_SYS_HZ);
63
64 /* try guess - 1 */
65 if (guess > 0) {
66 err2 = ABSDIFF(remainder * 1000, (guess - 1) * CONFIG_SYS_HZ);
67 if (err2 < err) {
68 milliseconds = guess - 1;
69 err = err2;
70 }
71 }
72
73 /* try guess + 1 */
74 if (guess < 999) {
75 err2 = ABSDIFF(remainder * 1000, (guess + 1) * CONFIG_SYS_HZ);
76 if (err2 < err) {
77 milliseconds = guess + 1;
78 err = err2;
79 }
80 }
81
82 printf("time:");
83 if (minutes)
84 printf(" %lu minutes and", minutes);
sjg 2011/04/05 01:21:44 It might be easier for a test system to parse if y
Che-Liang Chiou 2011/04/06 08:48:40 Done.
85 printf(" %lu.%03lu seconds, or", seconds, milliseconds);
86 printf(" %lu ticks\n", cycles);
87 #else
88 printf("CONFIG_SYS_HZ not defined\n");
89 printf("time: %lu ticks\n", cycles);
90 #endif
91 }
92
93 int do_time(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
94 {
95 const int target_argc = argc - 1;
96 int retval = 0;
97 unsigned long int cycles = 0;
98 cmd_tbl_t *target_cmdtp = NULL;
99
100 if (argc == 1) {
101 printf("no command provided\n");
102 return 128;
sjg 2011/04/05 01:21:44 What is the significance of 128? Is it argument er
Che-Liang Chiou 2011/04/06 08:48:40 I thought that we might be able to know either it
103 }
104
105 /* parse command */
106 target_cmdtp = find_cmd(argv[1]);
107 if (!target_cmdtp) {
108 printf("command not found: %s\n", argv[1]);
109 return 128;
110 }
111
112 if (target_argc > target_cmdtp->maxargs) {
113 printf("maxarags exceeded: %d > %d\n", target_argc,
114 target_cmdtp->maxargs);
115 return 128;
116 }
117
118 /* run the command and report run time */
119 cycles = get_timer_masked();
120 retval = target_cmdtp->cmd(target_cmdtp, 0, target_argc, argv + 1);
121 cycles = get_timer_masked() - cycles;
122
123 putc('\n');
124 report_time(cycles);
125
126 return retval;
127 }
128
129 U_BOOT_CMD(time, CONFIG_SYS_MAXARGS, 0, do_time,
130 "run a command and report its run time",
131 "command [args...]\n"
132 "the return value of time is the return value of "
133 "the command it executed, "
134 "or 128 if there is an internal error of time.\n");
OLDNEW
« no previous file with comments | « common/Makefile ('k') | include/config_cmd_all.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698