Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "base/process/process_metrics.h" | 5 #include "base/process/process_metrics.h" |
| 6 | 6 |
| 7 #include <dirent.h> | 7 #include <dirent.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 #include <sys/time.h> | 10 #include <sys/time.h> |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 69 NOTREACHED(); | 69 NOTREACHED(); |
| 70 return 0; | 70 return 0; |
| 71 } | 71 } |
| 72 return value; | 72 return value; |
| 73 } | 73 } |
| 74 } | 74 } |
| 75 NOTREACHED(); | 75 NOTREACHED(); |
| 76 return 0; | 76 return 0; |
| 77 } | 77 } |
| 78 | 78 |
| 79 // Read /proc/<pid>/sched and look for |field|. On succes, return true and | |
| 80 // write the value for |field| into |result|. | |
| 81 // Only works for fields in the form of "field : uint_value" | |
| 82 bool ReadProcSchedAndGetFieldAsUint64(pid_t pid, | |
| 83 const std::string& field, | |
| 84 uint64* result) { | |
| 85 std::string sched_data; | |
| 86 { | |
| 87 // Synchronously reading files in /proc is safe. | |
|
Nico
2014/09/07 00:10:57
"safe" isn't why we have this, it's about speed. I
Lei Zhang
2014/09/09 06:13:14
Filed all over. It's copy+pasted from elsewhere in
| |
| 88 ThreadRestrictions::ScopedAllowIO allow_io; | |
| 89 FilePath sched_file = internal::GetProcPidDir(pid).Append("sched"); | |
| 90 if (!ReadFileToString(sched_file, &sched_data)) | |
| 91 return false; | |
| 92 } | |
| 93 | |
| 94 std::vector<std::pair<std::string, std::string> > pairs; | |
| 95 SplitStringIntoKeyValuePairs(sched_data, ':', '\n', &pairs); | |
| 96 for (size_t i = 0; i < pairs.size(); ++i) { | |
| 97 std::string key, value_str; | |
| 98 TrimWhitespaceASCII(pairs[i].first, TRIM_ALL, &key); | |
| 99 TrimWhitespaceASCII(pairs[i].second, TRIM_ALL, &value_str); | |
|
Nico
2014/09/07 00:10:57
This looks pretty similar to line 72 of https://co
Lei Zhang
2014/09/09 06:13:14
Done.
| |
| 100 if (key == field) { | |
| 101 uint64 value; | |
| 102 if (!StringToUint64(value_str, &value)) | |
| 103 return false; | |
| 104 *result = value; | |
| 105 return true; | |
| 106 } | |
| 107 } | |
| 108 return false; | |
| 109 } | |
| 110 | |
| 79 // Get the total CPU of a single process. Return value is number of jiffies | 111 // Get the total CPU of a single process. Return value is number of jiffies |
| 80 // on success or -1 on error. | 112 // on success or -1 on error. |
| 81 int GetProcessCPU(pid_t pid) { | 113 int GetProcessCPU(pid_t pid) { |
| 82 // Use /proc/<pid>/task to find all threads and parse their /stat file. | 114 // Use /proc/<pid>/task to find all threads and parse their /stat file. |
| 83 FilePath task_path = internal::GetProcPidDir(pid).Append("task"); | 115 FilePath task_path = internal::GetProcPidDir(pid).Append("task"); |
| 84 | 116 |
| 85 DIR* dir = opendir(task_path.value().c_str()); | 117 DIR* dir = opendir(task_path.value().c_str()); |
| 86 if (!dir) { | 118 if (!dir) { |
| 87 DPLOG(ERROR) << "opendir(" << task_path.value() << ")"; | 119 DPLOG(ERROR) << "opendir(" << task_path.value() << ")"; |
| 88 return -1; | 120 return -1; |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 227 continue; | 259 continue; |
| 228 bool converted = StringToUint64(value_str, target_counter); | 260 bool converted = StringToUint64(value_str, target_counter); |
| 229 DCHECK(converted); | 261 DCHECK(converted); |
| 230 } | 262 } |
| 231 return true; | 263 return true; |
| 232 } | 264 } |
| 233 | 265 |
| 234 ProcessMetrics::ProcessMetrics(ProcessHandle process) | 266 ProcessMetrics::ProcessMetrics(ProcessHandle process) |
| 235 : process_(process), | 267 : process_(process), |
| 236 last_system_time_(0), | 268 last_system_time_(0), |
| 269 last_absolute_idle_wakeups_(0), | |
| 237 last_cpu_(0) { | 270 last_cpu_(0) { |
| 238 processor_count_ = SysInfo::NumberOfProcessors(); | 271 processor_count_ = SysInfo::NumberOfProcessors(); |
| 239 } | 272 } |
| 240 | 273 |
| 241 #if defined(OS_CHROMEOS) | 274 #if defined(OS_CHROMEOS) |
| 242 // Private, Shared and Proportional working set sizes are obtained from | 275 // Private, Shared and Proportional working set sizes are obtained from |
| 243 // /proc/<pid>/totmaps | 276 // /proc/<pid>/totmaps |
| 244 bool ProcessMetrics::GetWorkingSetKBytesTotmaps(WorkingSetKBytes *ws_usage) | 277 bool ProcessMetrics::GetWorkingSetKBytesTotmaps(WorkingSetKBytes *ws_usage) |
| 245 const { | 278 const { |
| 246 // The format of /proc/<pid>/totmaps is: | 279 // The format of /proc/<pid>/totmaps is: |
| (...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 832 swap_info->orig_data_size = orig_data_size; | 865 swap_info->orig_data_size = orig_data_size; |
| 833 swap_info->num_reads = ReadFileToUint64(zram_path.Append("num_reads")); | 866 swap_info->num_reads = ReadFileToUint64(zram_path.Append("num_reads")); |
| 834 swap_info->num_writes = ReadFileToUint64(zram_path.Append("num_writes")); | 867 swap_info->num_writes = ReadFileToUint64(zram_path.Append("num_writes")); |
| 835 swap_info->compr_data_size = | 868 swap_info->compr_data_size = |
| 836 ReadFileToUint64(zram_path.Append("compr_data_size")); | 869 ReadFileToUint64(zram_path.Append("compr_data_size")); |
| 837 swap_info->mem_used_total = | 870 swap_info->mem_used_total = |
| 838 ReadFileToUint64(zram_path.Append("mem_used_total")); | 871 ReadFileToUint64(zram_path.Append("mem_used_total")); |
| 839 } | 872 } |
| 840 #endif // defined(OS_CHROMEOS) | 873 #endif // defined(OS_CHROMEOS) |
| 841 | 874 |
| 875 int ProcessMetrics::GetIdleWakeupsPerSecond() { | |
| 876 uint64 wake_ups; | |
| 877 const char kWakeupStat[] = "se.statistics.nr_wakeups"; | |
| 878 return ReadProcSchedAndGetFieldAsUint64(process_, kWakeupStat, &wake_ups) ? | |
| 879 CalculateIdleWakeupsPerSecond(wake_ups) : 0; | |
| 880 } | |
| 881 | |
| 842 } // namespace base | 882 } // namespace base |
| OLD | NEW |