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

Side by Side Diff: chrome/browser/chromeos/power/cpu_data_collector.cc

Issue 2853863002: Add parser for new cpu freq file (Closed)
Patch Set: Created 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/power/cpu_data_collector.h" 5 #include "chrome/browser/chromeos/power/cpu_data_collector.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 freq_sample->time_in_state[index] = occupancy_time_centisecond * 10; 234 freq_sample->time_in_state[index] = occupancy_time_centisecond * 10;
235 } else { 235 } else {
236 LOG(ERROR) << "Bad format in " << path << ". " 236 LOG(ERROR) << "Bad format in " << path << ". "
237 << "Dropping sample."; 237 << "Dropping sample.";
238 return false; 238 return false;
239 } 239 }
240 } 240 }
241 return true; 241 return true;
242 } 242 }
243 243
244 bool ReadCpuFreqFromNewFile(
Daniel Erat 2017/05/01 19:46:32 "old file" and "new file" aren't very descriptive.
weidongg 2017/05/02 22:16:16 Done.
245 int cpu_count,
246 const std::string& path,
247 std::vector<std::string>* cpu_freq_state_names,
Daniel Erat 2017/05/01 22:28:38 high-level question about this code: is there any
weidongg 2017/05/02 22:16:15 It seems that the author intentionally separated t
248 std::vector<CpuDataCollector::StateOccupancySample>* freq_samples) {
Daniel Erat 2017/05/01 19:46:32 please document all of these parameters. freq_samp
weidongg 2017/05/02 22:16:16 Done.
249 std::string time_in_state_string;
250 // Note time as close to reading the file as possible. This is
251 // not possible for idle state samples as the information for
252 // each state there is recorded in different files.
253 if (!base::ReadFileToString(base::FilePath(path), &time_in_state_string)) {
254 LOG(ERROR) << "Error reading " << path << ". "
255 << "Dropping sample.";
256 return false;
257 }
258
259 std::vector<base::StringPiece> lines = base::SplitStringPiece(
260 time_in_state_string, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
261 // The last line could end with '\n'. Ignore the last empty string in
262 // such cases.
263 size_t state_count = lines.size();
264 if (state_count > 0 && lines.back().empty())
265 state_count -= 1;
Daniel Erat 2017/05/01 19:46:32 consider just using base::TrimWhitespaceASCII on t
weidongg 2017/05/02 22:16:16 Done.
266 // The first line is descriptions in the format "freq\t\tcpu0\t\tcpu1...".
267 if (state_count > 0) {
Daniel Erat 2017/05/01 19:46:32 if lines is empty, shouldn't you just return false
weidongg 2017/05/02 22:16:15 Yes, it is supposed to return false.
268 state_count -= 1;
269 lines.erase(lines.begin());
270 }
271 for (size_t state = 0; state < state_count; ++state) {
272 int freq_in_khz;
273
274 // Occupancy of each state is in the format "<state>\t\t<time>\t\t<time>
275 // ..."
276 std::vector<base::StringPiece> array = base::SplitStringPiece(
277 lines[state], "\t", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
278 if (array.size() == size_t(cpu_count) + 1 &&
279 base::StringToInt(array[0], &freq_in_khz)) {
280 const std::string state_name = base::IntToString(freq_in_khz / 1000);
281 size_t index = IndexInVector(state_name, cpu_freq_state_names);
Daniel Erat 2017/05/01 19:46:32 presumably you need to check the index here.
weidongg 2017/05/01 21:50:10 the index returned is always valid, as the state_n
Daniel Erat 2017/05/01 22:28:38 sorry, i was confused by the name IndexInVector. w
weidongg 2017/05/02 22:16:16 Done.
282 for (int cpu = 0; cpu < cpu_count; ++cpu) {
283 if (!(*freq_samples)[cpu].cpu_online) {
284 continue;
285 }
286 if (index >= (*freq_samples)[cpu].time_in_state.size())
287 (*freq_samples)[cpu].time_in_state.resize(index + 1);
288 int64_t occupancy_time_centisecond;
289 base::StringToInt64(array[cpu + 1], &occupancy_time_centisecond);
Daniel Erat 2017/05/01 19:46:32 you need to check the return value of this convers
weidongg 2017/05/02 22:16:15 Done.
290 (*freq_samples)[cpu].time_in_state[index] =
291 occupancy_time_centisecond * 10;
292 }
293 } else {
Daniel Erat 2017/05/01 19:46:32 test for bad input and return false immediately; t
weidongg 2017/05/01 21:50:10 Sorry, I don't understand, could you be more speci
Daniel Erat 2017/05/01 22:28:38 i mean this code would be simpler if you did: i
weidongg 2017/05/02 22:16:15 Ok, I see. Yes, that's better.
294 LOG(ERROR) << "Bad format in " << path << ". "
295 << "Dropping sample.";
296 return false;
297 }
298 }
299 return true;
300 }
301
244 // Samples the CPU freq state information from sysfs. |cpu_count| is the number 302 // Samples the CPU freq state information from sysfs. |cpu_count| is the number
245 // of possible CPUs on the system. Sample at index i in |freq_samples| 303 // of possible CPUs on the system. Sample at index i in |freq_samples|
246 // corresponds to the freq state information of the i-th CPU. 304 // corresponds to the freq state information of the i-th CPU.
247 void SampleCpuFreqData( 305 void SampleCpuFreqData(
248 int cpu_count, 306 int cpu_count,
249 std::vector<std::string>* cpu_freq_state_names, 307 std::vector<std::string>* cpu_freq_state_names,
250 std::vector<CpuDataCollector::StateOccupancySample>* freq_samples) { 308 std::vector<CpuDataCollector::StateOccupancySample>* freq_samples) {
251 base::Time start_time = base::Time::Now(); 309 base::Time start_time = base::Time::Now();
252 for (int cpu = 0; cpu < cpu_count; ++cpu) { 310 for (int cpu = 0; cpu < cpu_count; ++cpu) {
253 CpuDataCollector::StateOccupancySample freq_sample; 311 CpuDataCollector::StateOccupancySample freq_sample;
254 freq_sample.time_in_state.reserve(cpu_freq_state_names->size()); 312 freq_sample.time_in_state.reserve(cpu_freq_state_names->size());
313 freq_sample.time = base::Time::Now();
314 freq_sample.cpu_online = CpuIsOnline(cpu);
315 freq_samples->push_back(freq_sample);
316 }
255 317
256 freq_sample.time = base::Time::Now(); 318 if (!base::PathExists(base::FilePath(kCpuFreqTimeInStateNewPath))) {
257 if (!CpuIsOnline(cpu)) { 319 if (!ReadCpuFreqFromNewFile(cpu_count, kCpuFreqTimeInStateNewPath,
258 freq_sample.cpu_online = false; 320 cpu_freq_state_names, freq_samples)) {
259 } else { 321 freq_samples->clear();
260 freq_sample.cpu_online = true; 322 return;
261 323 }
262 const std::string time_in_state_path_old_format = base::StringPrintf( 324 } else {
263 "%s%s", kCpuDataPathBase, kCpuFreqTimeInStatePathSuffixOldFormat); 325 for (int cpu = 0; cpu < cpu_count; ++cpu) {
264 const std::string time_in_state_path = 326 if ((*freq_samples)[cpu].cpu_online) {
265 base::StringPrintf(time_in_state_path_old_format.c_str(), cpu); 327 const std::string time_in_state_path_old_format = base::StringPrintf(
266 if (base::PathExists(base::FilePath(time_in_state_path))) { 328 "%s%s", kCpuDataPathBase, kCpuFreqTimeInStatePathSuffixOldFormat);
267 if (!ReadCpuFreqFromOldFile(time_in_state_path, cpu_freq_state_names, 329 const std::string time_in_state_path =
268 &freq_sample)) { 330 base::StringPrintf(time_in_state_path_old_format.c_str(), cpu);
331 if (base::PathExists(base::FilePath(time_in_state_path))) {
332 if (!ReadCpuFreqFromOldFile(time_in_state_path, cpu_freq_state_names,
333 &(*freq_samples)[cpu])) {
334 freq_samples->clear();
335 return;
336 }
337 } else {
338 // If the path to the 'time_in_state' for a single CPU is missing,
339 // then 'time_in_state' for all CPUs is missing. This could happen
340 // on a VM where the 'cpufreq_stats' kernel module is not loaded.
341 LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
342 << "CPU freq stats not available in sysfs.";
269 freq_samples->clear(); 343 freq_samples->clear();
270 return; 344 return;
271 } 345 }
272 } else if (base::PathExists(base::FilePath(kCpuFreqTimeInStateNewPath))) {
273 // TODO(oshima): Parse the new file. crbug.com/548510.
274 freq_samples->clear();
275 return;
276 } else {
277 // If the path to the 'time_in_state' for a single CPU is missing,
278 // then 'time_in_state' for all CPUs is missing. This could happen
279 // on a VM where the 'cpufreq_stats' kernel module is not loaded.
280 LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
281 << "CPU freq stats not available in sysfs.";
282 freq_samples->clear();
283 return;
284 } 346 }
285 } 347 }
286
287 freq_samples->push_back(freq_sample);
288 } 348 }
289
290 // If there was an interruption in sampling (like system suspended), 349 // If there was an interruption in sampling (like system suspended),
291 // discard the samples! 350 // discard the samples!
292 int64_t delay = 351 int64_t delay =
293 base::TimeDelta(base::Time::Now() - start_time).InMilliseconds(); 352 base::TimeDelta(base::Time::Now() - start_time).InMilliseconds();
294 if (delay > kSamplingDurationLimitMs) { 353 if (delay > kSamplingDurationLimitMs) {
295 freq_samples->clear(); 354 freq_samples->clear();
296 LOG(WARNING) << "Dropped a freq state sample due to excessive time delay: " 355 LOG(WARNING) << "Dropped a freq state sample due to excessive time delay: "
297 << delay << "milliseconds."; 356 << delay << "milliseconds.";
298 } 357 }
299 } 358 }
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 : cpu_online(false) { 499 : cpu_online(false) {
441 } 500 }
442 501
443 CpuDataCollector::StateOccupancySample::StateOccupancySample( 502 CpuDataCollector::StateOccupancySample::StateOccupancySample(
444 const StateOccupancySample& other) = default; 503 const StateOccupancySample& other) = default;
445 504
446 CpuDataCollector::StateOccupancySample::~StateOccupancySample() { 505 CpuDataCollector::StateOccupancySample::~StateOccupancySample() {
447 } 506 }
448 507
449 } // namespace chromeos 508 } // namespace chromeos
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698