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

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

Issue 2853863002: Add parser for new cpu freq file (Closed)
Patch Set: Add '// testing::Test:' 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
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
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/files/file_util.h"
13 #include "base/logging.h" 12 #include "base/logging.h"
14 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
16 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
18 #include "base/sys_info.h" 17 #include "base/sys_info.h"
19 #include "base/task_scheduler/post_task.h" 18 #include "base/task_scheduler/post_task.h"
20 #include "chrome/browser/chromeos/power/power_data_collector.h" 19 #include "chrome/browser/chromeos/power/power_data_collector.h"
21 #include "content/public/browser/browser_thread.h" 20 #include "content/public/browser/browser_thread.h"
22 21
(...skipping 18 matching lines...) Expand all
41 // Suffix of the path to the file listing the range of possible CPUs on the 40 // Suffix of the path to the file listing the range of possible CPUs on the
42 // system. 41 // system.
43 const char kPossibleCpuPathSuffix[] = "/possible"; 42 const char kPossibleCpuPathSuffix[] = "/possible";
44 43
45 // Format of the suffix of the path to the file which contains information 44 // Format of the suffix of the path to the file which contains information
46 // about a particular CPU being online or offline. 45 // about a particular CPU being online or offline.
47 const char kCpuOnlinePathSuffixFormat[] = "/cpu%d/online"; 46 const char kCpuOnlinePathSuffixFormat[] = "/cpu%d/online";
48 47
49 // Format of the suffix of the path to the file which contains freq state 48 // Format of the suffix of the path to the file which contains freq state
50 // information of a CPU. 49 // information of a CPU.
51 const char kCpuFreqTimeInStatePathSuffixOldFormat[] = 50 const char kCpuFreqTimeInStatePathSuffixFormat[] =
52 "/cpu%d/cpufreq/stats/time_in_state"; 51 "/cpu%d/cpufreq/stats/time_in_state";
53 52
54 // The path to the file which contains cpu freq state informatino of a CPU 53 // The path to the file which contains cpu freq state information of a CPU
55 // in newer kernel. 54 // in 3.14.0 or newer kernels.
56 const char kCpuFreqTimeInStateNewPath[] = 55 const char kCpuFreqAllTimeInStatePath[] =
57 "/sys/devices/system/cpu/cpufreq/all_time_in_state"; 56 "/sys/devices/system/cpu/cpufreq/all_time_in_state";
58 57
59 // Format of the suffix of the path to the directory which contains information 58 // Format of the suffix of the path to the directory which contains information
60 // about an idle state of a CPU on the system. 59 // about an idle state of a CPU on the system.
61 const char kCpuIdleStateDirPathSuffixFormat[] = "/cpu%d/cpuidle/state%d"; 60 const char kCpuIdleStateDirPathSuffixFormat[] = "/cpu%d/cpuidle/state%d";
62 61
63 // Format of the suffix of the path to the file which contains the name of an 62 // Format of the suffix of the path to the file which contains the name of an
64 // idle state of a CPU. 63 // idle state of a CPU.
65 const char kCpuIdleStateNamePathSuffixFormat[] = "/cpu%d/cpuidle/state%d/name"; 64 const char kCpuIdleStateNamePathSuffixFormat[] = "/cpu%d/cpuidle/state%d/name";
66 65
67 // Format of the suffix of the path which contains information about time spent 66 // Format of the suffix of the path which contains information about time spent
68 // in an idle state on a CPU. 67 // in an idle state on a CPU.
69 const char kCpuIdleStateTimePathSuffixFormat[] = "/cpu%d/cpuidle/state%d/time"; 68 const char kCpuIdleStateTimePathSuffixFormat[] = "/cpu%d/cpuidle/state%d/time";
70 69
71 // Returns the index at which |str| is in |vector|. If |str| is not present in 70 // Returns the index at which |str| is in |vector|. If |str| is not present in
72 // |vector|, then it is added to it before its index is returned. 71 // |vector|, then it is added to it before its index is returned.
73 size_t IndexInVector(const std::string& str, std::vector<std::string>* vector) { 72 size_t EnsureInVector(const std::string& str,
73 std::vector<std::string>* vector) {
74 for (size_t i = 0; i < vector->size(); ++i) { 74 for (size_t i = 0; i < vector->size(); ++i) {
75 if (str == (*vector)[i]) 75 if (str == (*vector)[i])
76 return i; 76 return i;
77 } 77 }
78 78
79 // If this is reached, then it means |str| is not present in vector. Add it. 79 // If this is reached, then it means |str| is not present in vector. Add it.
80 vector->push_back(str); 80 vector->push_back(str);
81 return vector->size() - 1; 81 return vector->size() - 1;
82 } 82 }
83 83
(...skipping 17 matching lines...) Expand all
101 &cpu_online_string); 101 &cpu_online_string);
102 if (base::StringToInt(cpu_online_string, &online)) 102 if (base::StringToInt(cpu_online_string, &online))
103 return online == kCpuOnlineStatus; 103 return online == kCpuOnlineStatus;
104 } 104 }
105 105
106 LOG(ERROR) << "Bad format or error reading " << cpu_online_file << ". " 106 LOG(ERROR) << "Bad format or error reading " << cpu_online_file << ". "
107 << "Assuming offline."; 107 << "Assuming offline.";
108 return false; 108 return false;
109 } 109 }
110 110
111 // Samples the CPU idle state information from sysfs. |cpu_count| is the number 111 // Samples the CPU idle state information from sysfs. |cpu_count| is the
112 // of possible CPUs on the system. Sample at index i in |idle_samples| 112 // number of possible CPUs on the system. Sample at index i in |idle_samples|
113 // corresponds to the idle state information of the i-th CPU. 113 // corresponds to the idle state information of the i-th CPU.
114 void SampleCpuIdleData( 114 void SampleCpuIdleData(
115 int cpu_count, 115 int cpu_count,
116 std::vector<std::string>* cpu_idle_state_names, 116 std::vector<std::string>* cpu_idle_state_names,
117 std::vector<CpuDataCollector::StateOccupancySample>* idle_samples) { 117 std::vector<CpuDataCollector::StateOccupancySample>* idle_samples) {
118 base::Time start_time = base::Time::Now(); 118 base::Time start_time = base::Time::Now();
119 for (int cpu = 0; cpu < cpu_count; ++cpu) { 119 for (int cpu = 0; cpu < cpu_count; ++cpu) {
120 CpuDataCollector::StateOccupancySample idle_sample; 120 CpuDataCollector::StateOccupancySample idle_sample;
121 idle_sample.time = base::Time::Now(); 121 idle_sample.time = base::Time::Now();
122 idle_sample.time_in_state.reserve(cpu_idle_state_names->size()); 122 idle_sample.time_in_state.reserve(cpu_idle_state_names->size());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 LOG(ERROR) << "Error reading idle state from " 160 LOG(ERROR) << "Error reading idle state from "
161 << idle_state_dir << ". Dropping sample."; 161 << idle_state_dir << ". Dropping sample.";
162 idle_samples->clear(); 162 idle_samples->clear();
163 return; 163 return;
164 } 164 }
165 165
166 base::TrimWhitespaceASCII(state_name, base::TRIM_ALL, &state_name); 166 base::TrimWhitespaceASCII(state_name, base::TRIM_ALL, &state_name);
167 base::TrimWhitespaceASCII(occupancy_time_string, base::TRIM_ALL, 167 base::TrimWhitespaceASCII(occupancy_time_string, base::TRIM_ALL,
168 &occupancy_time_string); 168 &occupancy_time_string);
169 if (base::StringToInt64(occupancy_time_string, &occupancy_time_usec)) { 169 if (base::StringToInt64(occupancy_time_string, &occupancy_time_usec)) {
170 // idle state occupancy time in sysfs is recorded in microseconds. 170 size_t index = EnsureInVector(state_name, cpu_idle_state_names);
171 int64_t time_in_state_ms = occupancy_time_usec / 1000;
172 size_t index = IndexInVector(state_name, cpu_idle_state_names);
173 if (index >= idle_sample.time_in_state.size()) 171 if (index >= idle_sample.time_in_state.size())
174 idle_sample.time_in_state.resize(index + 1); 172 idle_sample.time_in_state.resize(index + 1);
175 idle_sample.time_in_state[index] = time_in_state_ms; 173 idle_sample.time_in_state[index] =
174 base::TimeDelta::FromMicroseconds(occupancy_time_usec);
176 } else { 175 } else {
177 LOG(ERROR) << "Bad format in " << time_file_path << ". " 176 LOG(ERROR) << "Bad format in " << time_file_path << ". "
178 << "Dropping sample."; 177 << "Dropping sample.";
179 idle_samples->clear(); 178 idle_samples->clear();
180 return; 179 return;
181 } 180 }
182 } 181 }
183 } 182 }
184 183
185 idle_samples->push_back(idle_sample); 184 idle_samples->push_back(idle_sample);
186 } 185 }
187 186
188 // If there was an interruption in sampling (like system suspended), 187 // If there was an interruption in sampling (like system suspended),
189 // discard the samples! 188 // discard the samples!
190 int64_t delay = 189 int64_t delay =
191 base::TimeDelta(base::Time::Now() - start_time).InMilliseconds(); 190 base::TimeDelta(base::Time::Now() - start_time).InMilliseconds();
192 if (delay > kSamplingDurationLimitMs) { 191 if (delay > kSamplingDurationLimitMs) {
193 idle_samples->clear(); 192 idle_samples->clear();
194 LOG(WARNING) << "Dropped an idle state sample due to excessive time delay: " 193 LOG(WARNING) << "Dropped an idle state sample due to excessive time delay: "
195 << delay << "milliseconds."; 194 << delay << "milliseconds.";
196 } 195 }
197 } 196 }
198 197
199 bool ReadCpuFreqFromOldFile( 198 // Samples the CPU freq state information from sysfs. |cpu_count| is the
200 const std::string& path, 199 // number of possible CPUs on the system. Sample at index i in |freq_samples|
201 std::vector<std::string>* cpu_freq_state_names,
202 CpuDataCollector::StateOccupancySample* freq_sample) {
203 std::string time_in_state_string;
204 // Note time as close to reading the file as possible. This is
205 // not possible for idle state samples as the information for
206 // each state there is recorded in different files.
207 if (!base::ReadFileToString(base::FilePath(path), &time_in_state_string)) {
208 LOG(ERROR) << "Error reading " << path << ". "
209 << "Dropping sample.";
210 return false;
211 }
212
213 std::vector<base::StringPiece> lines = base::SplitStringPiece(
214 time_in_state_string, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
215 // The last line could end with '\n'. Ignore the last empty string in
216 // such cases.
217 size_t state_count = lines.size();
218 if (state_count > 0 && lines.back().empty())
219 state_count -= 1;
220 for (size_t state = 0; state < state_count; ++state) {
221 int freq_in_khz;
222 int64_t occupancy_time_centisecond;
223
224 // Occupancy of each state is in the format "<state> <time>"
225 std::vector<base::StringPiece> pair = base::SplitStringPiece(
226 lines[state], " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
227 if (pair.size() == 2 && base::StringToInt(pair[0], &freq_in_khz) &&
228 base::StringToInt64(pair[1], &occupancy_time_centisecond)) {
229 const std::string state_name = base::IntToString(freq_in_khz / 1000);
230 size_t index = IndexInVector(state_name, cpu_freq_state_names);
231 if (index >= freq_sample->time_in_state.size())
232 freq_sample->time_in_state.resize(index + 1);
233 // The occupancy time is in units of centiseconds.
234 freq_sample->time_in_state[index] = occupancy_time_centisecond * 10;
235 } else {
236 LOG(ERROR) << "Bad format in " << path << ". "
237 << "Dropping sample.";
238 return false;
239 }
240 }
241 return true;
242 }
243
244 // 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|
246 // corresponds to the freq state information of the i-th CPU. 200 // corresponds to the freq state information of the i-th CPU.
247 void SampleCpuFreqData( 201 void SampleCpuFreqData(
248 int cpu_count, 202 int cpu_count,
249 std::vector<std::string>* cpu_freq_state_names, 203 std::vector<std::string>* cpu_freq_state_names,
250 std::vector<CpuDataCollector::StateOccupancySample>* freq_samples) { 204 std::vector<CpuDataCollector::StateOccupancySample>* freq_samples) {
251 base::Time start_time = base::Time::Now(); 205 base::Time start_time = base::Time::Now();
252 for (int cpu = 0; cpu < cpu_count; ++cpu) { 206 for (int cpu = 0; cpu < cpu_count; ++cpu) {
253 CpuDataCollector::StateOccupancySample freq_sample; 207 CpuDataCollector::StateOccupancySample freq_sample;
254 freq_sample.time_in_state.reserve(cpu_freq_state_names->size()); 208 freq_sample.time_in_state.reserve(cpu_freq_state_names->size());
209 freq_sample.time = base::Time::Now();
210 freq_sample.cpu_online = CpuIsOnline(cpu);
211 freq_samples->push_back(freq_sample);
212 }
255 213
256 freq_sample.time = base::Time::Now(); 214 if (base::PathExists(base::FilePath(kCpuFreqAllTimeInStatePath))) {
257 if (!CpuIsOnline(cpu)) { 215 if (!CpuDataCollector::ReadCpuFreqAllTimeInState(
258 freq_sample.cpu_online = false; 216 cpu_count, base::FilePath(kCpuFreqAllTimeInStatePath),
259 } else { 217 cpu_freq_state_names, freq_samples)) {
260 freq_sample.cpu_online = true; 218 freq_samples->clear();
261 219 return;
262 const std::string time_in_state_path_old_format = base::StringPrintf( 220 }
263 "%s%s", kCpuDataPathBase, kCpuFreqTimeInStatePathSuffixOldFormat); 221 } else {
264 const std::string time_in_state_path = 222 for (int cpu = 0; cpu < cpu_count; ++cpu) {
265 base::StringPrintf(time_in_state_path_old_format.c_str(), cpu); 223 if ((*freq_samples)[cpu].cpu_online) {
266 if (base::PathExists(base::FilePath(time_in_state_path))) { 224 const std::string time_in_state_path_format = base::StringPrintf(
267 if (!ReadCpuFreqFromOldFile(time_in_state_path, cpu_freq_state_names, 225 "%s%s", kCpuDataPathBase, kCpuFreqTimeInStatePathSuffixFormat);
268 &freq_sample)) { 226 const base::FilePath time_in_state_path(
227 base::StringPrintf(time_in_state_path_format.c_str(), cpu));
228 if (base::PathExists(time_in_state_path)) {
229 if (!CpuDataCollector::ReadCpuFreqTimeInState(
230 time_in_state_path, cpu_freq_state_names,
231 &(*freq_samples)[cpu])) {
232 freq_samples->clear();
233 return;
234 }
235 } else {
236 // If the path to the 'time_in_state' for a single CPU is missing,
237 // then 'time_in_state' for all CPUs is missing. This could happen
238 // on a VM where the 'cpufreq_stats' kernel module is not loaded.
239 LOG_IF(ERROR, base::SysInfo::IsRunningOnChromeOS())
240 << "CPU freq stats not available in sysfs.";
269 freq_samples->clear(); 241 freq_samples->clear();
270 return; 242 return;
271 } 243 }
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 } 244 }
285 } 245 }
286
287 freq_samples->push_back(freq_sample);
288 } 246 }
289
290 // If there was an interruption in sampling (like system suspended), 247 // If there was an interruption in sampling (like system suspended),
291 // discard the samples! 248 // discard the samples!
292 int64_t delay = 249 int64_t delay =
293 base::TimeDelta(base::Time::Now() - start_time).InMilliseconds(); 250 base::TimeDelta(base::Time::Now() - start_time).InMilliseconds();
294 if (delay > kSamplingDurationLimitMs) { 251 if (delay > kSamplingDurationLimitMs) {
295 freq_samples->clear(); 252 freq_samples->clear();
296 LOG(WARNING) << "Dropped a freq state sample due to excessive time delay: " 253 LOG(WARNING) << "Dropped a freq state sample due to excessive time delay: "
297 << delay << "milliseconds."; 254 << delay << "milliseconds.";
298 } 255 }
299 } 256 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 } 302 }
346 } 303 }
347 304
348 // Initialize the deques in the data vectors. 305 // Initialize the deques in the data vectors.
349 SampleCpuIdleData(*cpu_count, cpu_idle_state_names, idle_samples); 306 SampleCpuIdleData(*cpu_count, cpu_idle_state_names, idle_samples);
350 SampleCpuFreqData(*cpu_count, cpu_freq_state_names, freq_samples); 307 SampleCpuFreqData(*cpu_count, cpu_freq_state_names, freq_samples);
351 } 308 }
352 309
353 } // namespace 310 } // namespace
354 311
312 bool CpuDataCollector::ReadCpuFreqTimeInState(
313 const base::FilePath& path,
314 std::vector<std::string>* cpu_freq_state_names,
315 CpuDataCollector::StateOccupancySample* freq_sample) {
316 std::string time_in_state_string;
317 // Note time as close to reading the file as possible. This is
318 // not possible for idle state samples as the information for
319 // each state there is recorded in different files.
320 if (!base::ReadFileToString(path, &time_in_state_string)) {
321 LOG(ERROR) << "Error reading " << path.value() << "; Dropping sample.";
322 return false;
323 }
324 // Remove trailing newlines.
325 base::TrimWhitespaceASCII(time_in_state_string,
326 base::TrimPositions::TRIM_TRAILING,
327 &time_in_state_string);
328
329 std::vector<base::StringPiece> lines = base::SplitStringPiece(
330 time_in_state_string, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
331 for (size_t line_num = 0; line_num < lines.size(); ++line_num) {
332 int freq_in_khz;
333 int64_t occupancy_time_centisecond;
334
335 // Occupancy of each state is in the format "<state> <time>"
336 std::vector<base::StringPiece> pair = base::SplitStringPiece(
337 lines[line_num], " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
338 if (pair.size() != 2 || !base::StringToInt(pair[0], &freq_in_khz) ||
339 !base::StringToInt64(pair[1], &occupancy_time_centisecond)) {
340 LOG(ERROR) << "Bad format at \"" << lines[line_num] << "\" in "
341 << path.value() << ". Dropping sample.";
342 return false;
343 }
344
345 const std::string state_name = base::IntToString(freq_in_khz / 1000);
346 size_t index = EnsureInVector(state_name, cpu_freq_state_names);
347 if (index >= freq_sample->time_in_state.size())
348 freq_sample->time_in_state.resize(index + 1);
349 freq_sample->time_in_state[index] =
350 base::TimeDelta::FromMilliseconds(occupancy_time_centisecond * 10);
351 }
352 return true;
353 }
354
355 bool CpuDataCollector::ReadCpuFreqAllTimeInState(
356 int cpu_count,
357 const base::FilePath& path,
358 std::vector<std::string>* cpu_freq_state_names,
359 std::vector<CpuDataCollector::StateOccupancySample>* freq_samples) {
360 std::string all_time_in_state_string;
361 // Note time as close to reading the file as possible. This is
362 // not possible for idle state samples as the information for
363 // each state there is recorded in different files.
364 if (!base::ReadFileToString(path, &all_time_in_state_string)) {
365 LOG(ERROR) << "Error reading " << path.value() << "; Dropping sample.";
366 return false;
367 }
368 // Remove trailing newlines.
369 base::TrimWhitespaceASCII(all_time_in_state_string,
370 base::TrimPositions::TRIM_TRAILING,
371 &all_time_in_state_string);
372
373 std::vector<base::StringPiece> lines =
374 base::SplitStringPiece(all_time_in_state_string, "\n",
375 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
376 // The first line is descriptions in the format "freq\t\tcpu0\t\tcpu1...".
377 // Skip the first line, which contains column names.
378 for (size_t line_num = 1; line_num < lines.size(); ++line_num) {
379 // Occupancy of each state is in the format "<state>\t\t<time>\t\t<time>
380 // ..."
381 std::vector<base::StringPiece> array =
382 base::SplitStringPiece(lines[line_num], "\t", base::TRIM_WHITESPACE,
383 base::SPLIT_WANT_NONEMPTY);
384 int freq_in_khz;
385 if (array.size() != static_cast<size_t>(cpu_count) + 1 ||
386 !base::StringToInt(array[0], &freq_in_khz)) {
387 LOG(ERROR) << "Bad format at \"" << lines[line_num] << "\" in "
388 << path.value() << ". Dropping sample.";
389 return false;
390 }
391
392 const std::string state_name = base::IntToString(freq_in_khz / 1000);
393 size_t index = EnsureInVector(state_name, cpu_freq_state_names);
394 for (int cpu = 0; cpu < cpu_count; ++cpu) {
395 if (!(*freq_samples)[cpu].cpu_online) {
396 continue;
397 }
398 if (index >= (*freq_samples)[cpu].time_in_state.size())
399 (*freq_samples)[cpu].time_in_state.resize(index + 1);
400 int64_t occupancy_time_centisecond;
401 if (!base::StringToInt64(array[cpu + 1], &occupancy_time_centisecond)) {
402 LOG(ERROR) << "Bad format at \"" << lines[line_num] << "\" in "
403 << path.value() << ". Dropping sample.";
404 return false;
405 }
406 (*freq_samples)[cpu].time_in_state[index] =
407 base::TimeDelta::FromMilliseconds(occupancy_time_centisecond * 10);
408 }
409 }
410 return true;
411 }
412
355 // Set |cpu_count_| to -1 and let SampleCpuStateAsync discover the 413 // Set |cpu_count_| to -1 and let SampleCpuStateAsync discover the
356 // correct number of CPUs. 414 // correct number of CPUs.
357 CpuDataCollector::CpuDataCollector() : cpu_count_(-1), weak_ptr_factory_(this) { 415 CpuDataCollector::CpuDataCollector() : cpu_count_(-1), weak_ptr_factory_(this) {
358 } 416 }
359 417
360 CpuDataCollector::~CpuDataCollector() { 418 CpuDataCollector::~CpuDataCollector() {
361 } 419 }
362 420
363 void CpuDataCollector::Start() { 421 void CpuDataCollector::Start() {
364 timer_.Start(FROM_HERE, 422 timer_.Start(FROM_HERE,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 : cpu_online(false) { 498 : cpu_online(false) {
441 } 499 }
442 500
443 CpuDataCollector::StateOccupancySample::StateOccupancySample( 501 CpuDataCollector::StateOccupancySample::StateOccupancySample(
444 const StateOccupancySample& other) = default; 502 const StateOccupancySample& other) = default;
445 503
446 CpuDataCollector::StateOccupancySample::~StateOccupancySample() { 504 CpuDataCollector::StateOccupancySample::~StateOccupancySample() {
447 } 505 }
448 506
449 } // namespace chromeos 507 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/power/cpu_data_collector.h ('k') | chrome/browser/chromeos/power/cpu_data_collector_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698