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

Side by Side Diff: chrome/browser/chromeos/boot_times_loader.cc

Issue 2112006: Cleaned up some constants for stats reading (Closed)
Patch Set: Review mods Created 10 years, 7 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/boot_times_loader.h" 5 #include "chrome/browser/chromeos/boot_times_loader.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/file_path.h" 10 #include "base/file_path.h"
11 #include "base/file_util.h" 11 #include "base/file_util.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/process_util.h" 13 #include "base/process_util.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "base/thread.h" 15 #include "base/thread.h"
16 #include "chrome/browser/browser_process.h" 16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/chrome_thread.h" 17 #include "chrome/browser/chrome_thread.h"
18 #include "chrome/common/chrome_switches.h" 18 #include "chrome/common/chrome_switches.h"
19 19
20 namespace {
21
22 typedef struct Stats {
23 std::string uptime;
24 std::string disk;
25
26 Stats() : uptime(std::string()), disk(std::string()) {}
27 };
28
29 }
30
20 namespace chromeos { 31 namespace chromeos {
21 32
22 // File uptime logs are located in. 33 // File uptime logs are located in.
23 static const char kLogPath[] = "/tmp"; 34 static const char kLogPath[] = "/tmp";
24 35 // Prefix for the time measurement files.
36 static const char kUptimePrefix[] = "uptime-";
37 // Prefix for the disk usage files.
38 static const char kDiskPrefix[] = "disk-";
39 // Name of the time that Chrome's main() is called.
40 static const char kChromeMain[] = "chrome-main";
25 // Delay in milliseconds between file read attempts. 41 // Delay in milliseconds between file read attempts.
26 static const int64 kReadAttemptDelayMs = 500; 42 static const int64 kReadAttemptDelayMs = 250;
27 43
28 BootTimesLoader::BootTimesLoader() : backend_(new Backend()) { 44 BootTimesLoader::BootTimesLoader() : backend_(new Backend()) {
29 } 45 }
30 46
31 BootTimesLoader::Handle BootTimesLoader::GetBootTimes( 47 BootTimesLoader::Handle BootTimesLoader::GetBootTimes(
32 CancelableRequestConsumerBase* consumer, 48 CancelableRequestConsumerBase* consumer,
33 BootTimesLoader::GetBootTimesCallback* callback) { 49 BootTimesLoader::GetBootTimesCallback* callback) {
34 if (!g_browser_process->file_thread()) { 50 if (!g_browser_process->file_thread()) {
35 // This should only happen if Chrome is shutting down, so we don't do 51 // This should only happen if Chrome is shutting down, so we don't do
36 // anything. 52 // anything.
(...skipping 11 matching lines...) Expand all
48 new CancelableRequest<GetBootTimesCallback>(callback)); 64 new CancelableRequest<GetBootTimesCallback>(callback));
49 AddRequest(request, consumer); 65 AddRequest(request, consumer);
50 66
51 ChromeThread::PostTask( 67 ChromeThread::PostTask(
52 ChromeThread::FILE, 68 ChromeThread::FILE,
53 FROM_HERE, 69 FROM_HERE,
54 NewRunnableMethod(backend_.get(), &Backend::GetBootTimes, request)); 70 NewRunnableMethod(backend_.get(), &Backend::GetBootTimes, request));
55 return request->handle(); 71 return request->handle();
56 } 72 }
57 73
58 // Executes command within a shell, allowing IO redirection. Searches
59 // for a whitespace delimited string prefixed by prefix in the output and
60 // returns it.
61 static std::string ExecuteInShell(
62 const std::string& command, const std::string& prefix) {
63 std::vector<std::string> args;
64 args.push_back("/bin/sh");
65 args.push_back("-c");
66 args.push_back(command);
67 CommandLine cmd(args);
68 std::string out;
69
70 if (base::GetAppOutput(cmd, &out)) {
71 size_t index = out.find(prefix);
72 if (index != std::string::npos) {
73 size_t value_index = index + prefix.size();
74 size_t whitespace_index = out.find(' ', value_index);
75 size_t chars_left = std::string::npos;
76 if (whitespace_index == std::string::npos)
77 whitespace_index = out.find('\n', value_index);
78 if (whitespace_index != std::string::npos)
79 chars_left = whitespace_index - value_index;
80 return out.substr(value_index, chars_left);
81 }
82 }
83 return std::string();
84 }
85
86 // Extracts the uptime value from files located in /tmp, returning the 74 // Extracts the uptime value from files located in /tmp, returning the
87 // value as a double in value. 75 // value as a double in value.
88 static bool GetUptime(const std::string& log, double* value) { 76 static bool GetTime(const std::string& log, double* value) {
89 FilePath log_dir(kLogPath); 77 FilePath log_dir(kLogPath);
90 FilePath log_file = log_dir.Append(log); 78 FilePath log_file = log_dir.Append(log);
91 std::string contents; 79 std::string contents;
92 *value = 0.0; 80 *value = 0.0;
93 if (file_util::ReadFileToString(log_file, &contents)) { 81 if (file_util::ReadFileToString(log_file, &contents)) {
94 size_t space_index = contents.find(' '); 82 size_t space_index = contents.find(' ');
95 size_t chars_left = 83 size_t chars_left =
96 space_index != std::string::npos ? space_index : std::string::npos; 84 space_index != std::string::npos ? space_index : std::string::npos;
97 std::string value_string = contents.substr(0, chars_left); 85 std::string value_string = contents.substr(0, chars_left);
98 return StringToDouble(value_string, value); 86 return StringToDouble(value_string, value);
99 } 87 }
100 return false; 88 return false;
101 } 89 }
102 90
103 void BootTimesLoader::Backend::GetBootTimes( 91 void BootTimesLoader::Backend::GetBootTimes(
104 scoped_refptr<GetBootTimesRequest> request) { 92 scoped_refptr<GetBootTimesRequest> request) {
105 const char* kInitialTSCCommand = "dmesg | grep 'Initial TSC value:'"; 93 const char* kFirmwareBootTime = "firmware-boot-time";
106 const char* kInitialTSCPrefix = "TSC value: "; 94 const char* kPreStartup = "pre-startup";
107 const char* kClockSpeedCommand = "dmesg | grep -e 'Detected.*processor'"; 95 const char* kChromeExec = "chrome-exec";
108 const char* kClockSpeedPrefix = "Detected "; 96 const char* kChromeMain = "chrome-main";
109 const char* kPreStartup = "uptime-pre-startup"; 97 const char* kXStarted = "x-started";
110 const char* kChromeExec = "uptime-chrome-exec"; 98 const char* kLoginPromptReady = "login-prompt-ready";
111 const char* kChromeMain = "uptime-chrome-main"; 99 std::string uptime_prefix = kUptimePrefix;
112 const char* kXStarted = "uptime-x-started";
113 const char* kLoginPromptReady = "uptime-login-prompt-ready";
114 100
115 if (request->canceled()) 101 if (request->canceled())
116 return; 102 return;
117 103
118 // Wait until login_prompt_ready is output by reposting. 104 // Wait until login_prompt_ready is output by reposting.
119 FilePath log_dir(kLogPath); 105 FilePath log_dir(kLogPath);
120 FilePath log_file = log_dir.Append(kLoginPromptReady); 106 FilePath log_file = log_dir.Append(kLoginPromptReady);
121 if (!file_util::PathExists(log_file)) { 107 if (!file_util::PathExists(log_file)) {
122 ChromeThread::PostDelayedTask( 108 ChromeThread::PostDelayedTask(
123 ChromeThread::FILE, 109 ChromeThread::FILE,
124 FROM_HERE, 110 FROM_HERE,
125 NewRunnableMethod(this, &Backend::GetBootTimes, request), 111 NewRunnableMethod(this, &Backend::GetBootTimes, request),
126 kReadAttemptDelayMs); 112 kReadAttemptDelayMs);
127 return; 113 return;
128 } 114 }
129 115
130 BootTimes boot_times; 116 BootTimes boot_times;
131 std::string tsc_value = ExecuteInShell(kInitialTSCCommand, kInitialTSCPrefix); 117
132 std::string speed_value = 118 GetTime(kFirmwareBootTime, &boot_times.firmware);
133 ExecuteInShell(kClockSpeedCommand, kClockSpeedPrefix); 119 GetTime(uptime_prefix + kPreStartup, &boot_times.pre_startup);
134 boot_times.firmware = 0; 120 GetTime(uptime_prefix + kXStarted, &boot_times.x_started);
135 if (!tsc_value.empty() && !speed_value.empty()) { 121 GetTime(uptime_prefix + kChromeExec, &boot_times.chrome_exec);
136 int64 tsc = 0; 122 GetTime(uptime_prefix + kChromeMain, &boot_times.chrome_main);
137 double speed = 0; 123 GetTime(uptime_prefix + kLoginPromptReady, &boot_times.login_prompt_ready);
138 if (StringToInt64(tsc_value, &tsc) &&
139 StringToDouble(speed_value, &speed) &&
140 speed > 0) {
141 boot_times.firmware = static_cast<double>(tsc) / (speed * 1000000);
142 }
143 }
144 GetUptime(kPreStartup, &boot_times.pre_startup);
145 GetUptime(kXStarted, &boot_times.x_started);
146 GetUptime(kChromeExec, &boot_times.chrome_exec);
147 GetUptime(kChromeMain, &boot_times.chrome_main);
148 GetUptime(kLoginPromptReady, &boot_times.login_prompt_ready);
149 124
150 request->ForwardResult( 125 request->ForwardResult(
151 GetBootTimesCallback::TupleType(request->handle(), boot_times)); 126 GetBootTimesCallback::TupleType(request->handle(), boot_times));
152 } 127 }
153 128
129 static void RecordStatsDelayed(
130 const std::string& name,
131 const std::string& uptime,
132 const std::string& disk) {
133 const FilePath log_path(kLogPath);
134 std::string disk_prefix = kDiskPrefix;
135 const FilePath uptime_output =
136 log_path.Append(FilePath(kUptimePrefix + name));
137 const FilePath disk_output = log_path.Append(FilePath(kDiskPrefix + name));
138
139 // Write out the files, ensuring that they don't exist already.
140 if (!file_util::PathExists(uptime_output))
141 file_util::WriteFile(uptime_output, uptime.data(), uptime.size());
142 if (!file_util::PathExists(disk_output))
143 file_util::WriteFile(disk_output, disk.data(), disk.size());
144 }
145
146 static void RecordStats(
147 const std::string& name, const Stats& stats) {
148 ChromeThread::PostTask(
149 ChromeThread::FILE, FROM_HERE,
150 NewRunnableFunction(RecordStatsDelayed, name, stats.uptime, stats.disk));
151 }
152
153 static Stats GetCurrentStats() {
154 const FilePath kProcUptime("/proc/uptime");
155 const FilePath kDiskStat("/sys/block/sda/stat");
156 Stats stats;
157
158 file_util::ReadFileToString(kProcUptime, &stats.uptime);
159 file_util::ReadFileToString(kDiskStat, &stats.disk);
160 return stats;
161 }
162
163 // static
164 void BootTimesLoader::RecordCurrentStats(const std::string& name) {
165 Stats stats = GetCurrentStats();
166 RecordStats(name, stats);
167 }
168
169 // Used to hold the stats at main().
170 static Stats chrome_main_stats_;
171
172 void BootTimesLoader::SaveChromeMainStats() {
173 chrome_main_stats_ = GetCurrentStats();
174 }
175
176 void BootTimesLoader::RecordChromeMainStats() {
177 RecordStats(kChromeMain, chrome_main_stats_);
178 }
179
154 } // namespace chromeos 180 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/boot_times_loader.h ('k') | chrome/browser/chromeos/browser_notification_observers.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698