OLD | NEW |
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 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_util.h" | 5 #include "base/process_util.h" |
6 | 6 |
7 #include <ctype.h> | 7 #include <ctype.h> |
8 #include <dirent.h> | 8 #include <dirent.h> |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <unistd.h> | 10 #include <unistd.h> |
11 #include <string> | 11 #include <string> |
12 #include <sys/types.h> | 12 #include <sys/types.h> |
13 #include <sys/wait.h> | 13 #include <sys/wait.h> |
14 | 14 |
15 #include "base/eintr_wrapper.h" | 15 #include "base/eintr_wrapper.h" |
16 #include "base/file_util.h" | 16 #include "base/file_util.h" |
17 #include "base/logging.h" | 17 #include "base/logging.h" |
18 #include "base/string_tokenizer.h" | 18 #include "base/string_tokenizer.h" |
19 #include "base/string_util.h" | 19 #include "base/string_util.h" |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 enum ParsingState { | 23 enum ParsingState { |
24 KEY_NAME, | 24 KEY_NAME, |
25 KEY_VALUE | 25 KEY_VALUE |
26 }; | 26 }; |
27 | 27 |
| 28 // Reads /proc/<pid>/stat and populates |proc_stats| with the values split by |
| 29 // spaces. |
| 30 void GetProcStats(pid_t pid, std::vector<std::string>* proc_stats) { |
| 31 FilePath stat_file("/proc"); |
| 32 stat_file = stat_file.Append(IntToString(pid)); |
| 33 stat_file = stat_file.Append("stat"); |
| 34 std::string mem_stats; |
| 35 if (!file_util::ReadFileToString(stat_file, &mem_stats)) |
| 36 return; |
| 37 SplitString(mem_stats, ' ', proc_stats); |
| 38 } |
| 39 |
28 } // namespace | 40 } // namespace |
29 | 41 |
30 namespace base { | 42 namespace base { |
31 | 43 |
32 bool LaunchApp(const std::vector<std::string>& argv, | 44 bool LaunchApp(const std::vector<std::string>& argv, |
33 const file_handle_mapping_vector& fds_to_remap, | 45 const file_handle_mapping_vector& fds_to_remap, |
34 bool wait, ProcessHandle* process_handle) { | 46 bool wait, ProcessHandle* process_handle) { |
35 pid_t pid = fork(); | 47 pid_t pid = fork(); |
36 if (pid < 0) | 48 if (pid < 0) |
37 return false; | 49 return false; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 | 192 |
181 bool NamedProcessIterator::IncludeEntry() { | 193 bool NamedProcessIterator::IncludeEntry() { |
182 // TODO(port): make this also work for non-ASCII filenames | 194 // TODO(port): make this also work for non-ASCII filenames |
183 if (WideToASCII(executable_name_) != entry_.szExeFile) | 195 if (WideToASCII(executable_name_) != entry_.szExeFile) |
184 return false; | 196 return false; |
185 if (!filter_) | 197 if (!filter_) |
186 return true; | 198 return true; |
187 return filter_->Includes(entry_.pid, entry_.ppid); | 199 return filter_->Includes(entry_.pid, entry_.ppid); |
188 } | 200 } |
189 | 201 |
| 202 // On linux, we return vsize. |
| 203 size_t ProcessMetrics::GetPagefileUsage() const { |
| 204 std::vector<std::string> proc_stats; |
| 205 GetProcStats(process_, &proc_stats); |
| 206 const size_t kVmSize = 22; |
| 207 if (proc_stats.size() > kVmSize) |
| 208 return static_cast<size_t>(StringToInt(proc_stats[kVmSize])); |
| 209 return 0; |
| 210 } |
| 211 |
| 212 size_t ProcessMetrics::GetPeakPagefileUsage() const { |
| 213 NOTIMPLEMENTED(); |
| 214 return 0; |
| 215 } |
| 216 |
| 217 // On linux, we return RSS. |
| 218 size_t ProcessMetrics::GetWorkingSetSize() const { |
| 219 std::vector<std::string> proc_stats; |
| 220 GetProcStats(process_, &proc_stats); |
| 221 const size_t kVmRss = 23; |
| 222 if (proc_stats.size() > kVmRss) { |
| 223 size_t num_pages = static_cast<size_t>(StringToInt(proc_stats[kVmRss])); |
| 224 return num_pages * getpagesize(); |
| 225 } |
| 226 return 0; |
| 227 } |
| 228 |
| 229 size_t ProcessMetrics::GetPeakWorkingSetSize() const { |
| 230 NOTIMPLEMENTED(); |
| 231 return 0; |
| 232 } |
| 233 |
190 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING | 234 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING |
191 // in your kernel configuration. | 235 // in your kernel configuration. |
192 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { | 236 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { |
193 std::string proc_io_contents; | 237 std::string proc_io_contents; |
194 if (!file_util::ReadFileToString(L"/proc/self/io", &proc_io_contents)) | 238 FilePath io_file("/proc"); |
| 239 io_file = io_file.Append(IntToString(process_)); |
| 240 io_file = io_file.Append("io"); |
| 241 if (!file_util::ReadFileToString(io_file, &proc_io_contents)) |
195 return false; | 242 return false; |
196 | 243 |
197 (*io_counters).OtherOperationCount = 0; | 244 (*io_counters).OtherOperationCount = 0; |
198 (*io_counters).OtherTransferCount = 0; | 245 (*io_counters).OtherTransferCount = 0; |
199 | 246 |
200 StringTokenizer tokenizer(proc_io_contents, ": \n"); | 247 StringTokenizer tokenizer(proc_io_contents, ": \n"); |
201 ParsingState state = KEY_NAME; | 248 ParsingState state = KEY_NAME; |
202 std::string last_key_name; | 249 std::string last_key_name; |
203 while (tokenizer.GetNext()) { | 250 while (tokenizer.GetNext()) { |
204 switch (state) { | 251 switch (state) { |
(...skipping 13 matching lines...) Expand all Loading... |
218 (*io_counters).WriteTransferCount = StringToInt64(tokenizer.token()); | 265 (*io_counters).WriteTransferCount = StringToInt64(tokenizer.token()); |
219 } | 266 } |
220 state = KEY_NAME; | 267 state = KEY_NAME; |
221 break; | 268 break; |
222 } | 269 } |
223 } | 270 } |
224 return true; | 271 return true; |
225 } | 272 } |
226 | 273 |
227 } // namespace base | 274 } // namespace base |
OLD | NEW |