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 | 5 |
6 #include "base/process_util.h" | 6 #include "base/process_util.h" |
7 | 7 |
8 #import <Cocoa/Cocoa.h> | 8 #import <Cocoa/Cocoa.h> |
9 #include <crt_externs.h> | 9 #include <crt_externs.h> |
10 #include <mach/mach.h> | 10 #include <mach/mach.h> |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 // Don't need to check the name, we did that w/in CheckForNextProcess. | 175 // Don't need to check the name, we did that w/in CheckForNextProcess. |
176 if (!filter_) | 176 if (!filter_) |
177 return true; | 177 return true; |
178 return filter_->Includes(entry_.pid, entry_.ppid); | 178 return filter_->Includes(entry_.pid, entry_.ppid); |
179 } | 179 } |
180 | 180 |
181 | 181 |
182 // ------------------------------------------------------------------------ | 182 // ------------------------------------------------------------------------ |
183 // NOTE: about ProcessMetrics | 183 // NOTE: about ProcessMetrics |
184 // | 184 // |
185 // Getting a mach task from a pid for another process requires permissions in | 185 // Mac doesn't have /proc, and getting a mach task from a pid for another |
186 // general, so there doesn't really seem to be a way to do these (and spinning | 186 // process requires permissions, so there doesn't really seem to be a way |
187 // up ps to fetch each stats seems dangerous to put in a base api for anyone to | 187 // to do these (and spinning up ps to fetch each stats seems dangerous to |
188 // call). Child processes ipc their port, so return something if available, | 188 // put in a base api for anyone to call. |
189 // otherwise return 0. | |
190 // | 189 // |
191 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { | 190 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { |
192 return false; | 191 return false; |
193 } | 192 } |
194 | 193 size_t ProcessMetrics::GetPagefileUsage() const { |
195 static bool GetTaskInfo(mach_port_t task, task_basic_info_64* task_info_data) { | 194 return 0; |
196 if (!task) | |
197 return false; | |
198 mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT; | |
199 kern_return_t kr = task_info(task, | |
200 TASK_BASIC_INFO_64, | |
201 reinterpret_cast<task_info_t>(task_info_data), | |
202 &count); | |
203 // Most likely cause for failure: |task| is a zombie. | |
204 return kr == KERN_SUCCESS; | |
205 } | 195 } |
206 | |
207 size_t ProcessMetrics::GetPagefileUsage() const { | |
208 task_basic_info_64 task_info_data; | |
209 if (!GetTaskInfo(TaskForPid(process_), &task_info_data)) | |
210 return 0; | |
211 return task_info_data.virtual_size; | |
212 } | |
213 | |
214 size_t ProcessMetrics::GetPeakPagefileUsage() const { | 196 size_t ProcessMetrics::GetPeakPagefileUsage() const { |
215 return 0; | 197 return 0; |
216 } | 198 } |
217 | |
218 size_t ProcessMetrics::GetWorkingSetSize() const { | 199 size_t ProcessMetrics::GetWorkingSetSize() const { |
219 task_basic_info_64 task_info_data; | 200 return 0; |
220 if (!GetTaskInfo(TaskForPid(process_), &task_info_data)) | |
221 return 0; | |
222 return task_info_data.resident_size; | |
223 } | 201 } |
224 | |
225 size_t ProcessMetrics::GetPeakWorkingSetSize() const { | 202 size_t ProcessMetrics::GetPeakWorkingSetSize() const { |
226 return 0; | 203 return 0; |
227 } | 204 } |
228 | 205 |
229 size_t ProcessMetrics::GetPrivateBytes() const { | 206 size_t ProcessMetrics::GetPrivateBytes() const { |
230 return 0; | 207 return 0; |
231 } | 208 } |
232 | 209 |
233 void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const { | 210 void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const { |
234 } | 211 } |
235 | 212 |
236 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { | 213 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { |
237 size_t priv = GetWorkingSetSize(); | 214 return false; |
238 if (!priv) | |
239 return false; | |
240 ws_usage->priv = priv / 1024; | |
241 ws_usage->shareable = 0; | |
242 ws_usage->shared = 0; | |
243 return true; | |
244 } | |
245 | |
246 #define TIME_VALUE_TO_TIMEVAL(a, r) do { \ | |
247 (r)->tv_sec = (a)->seconds; \ | |
248 (r)->tv_usec = (a)->microseconds; \ | |
249 } while (0) | |
250 | |
251 int ProcessMetrics::GetCPUUsage() { | |
252 mach_port_t task = TaskForPid(process_); | |
253 if (!task) | |
254 return 0; | |
255 | |
256 kern_return_t kr; | |
257 | |
258 // TODO(thakis): Libtop doesn't use thread info. How can they get away | |
259 // without it? | |
260 task_thread_times_info thread_info_data; | |
261 mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT; | |
262 kr = task_info(task, | |
263 TASK_THREAD_TIMES_INFO, | |
264 reinterpret_cast<task_info_t>(&thread_info_data), | |
265 &thread_info_count); | |
266 if (kr != KERN_SUCCESS) { | |
267 // Most likely cause: |task| is a zombie. | |
268 return 0; | |
269 } | |
270 | |
271 task_basic_info_64 task_info_data; | |
272 if (!GetTaskInfo(task, &task_info_data)) | |
273 return 0; | |
274 | |
275 /* Set total_time. */ | |
276 // thread info contains live time... | |
277 struct timeval user_timeval, system_timeval, task_timeval; | |
278 TIME_VALUE_TO_TIMEVAL(&thread_info_data.user_time, &user_timeval); | |
279 TIME_VALUE_TO_TIMEVAL(&thread_info_data.system_time, &system_timeval); | |
280 timeradd(&user_timeval, &system_timeval, &task_timeval); | |
281 | |
282 // ... task info contains terminated time. | |
283 TIME_VALUE_TO_TIMEVAL(&task_info_data.user_time, &user_timeval); | |
284 TIME_VALUE_TO_TIMEVAL(&task_info_data.system_time, &system_timeval); | |
285 timeradd(&user_timeval, &task_timeval, &task_timeval); | |
286 timeradd(&system_timeval, &task_timeval, &task_timeval); | |
287 | |
288 struct timeval now; | |
289 int retval = gettimeofday(&now, NULL); | |
290 if (retval) | |
291 return 0; | |
292 | |
293 int64 time = TimeValToMicroseconds(now); | |
294 int64 task_time = TimeValToMicroseconds(task_timeval); | |
295 | |
296 if ((last_system_time_ == 0) || (last_time_ == 0)) { | |
297 // First call, just set the last values. | |
298 last_system_time_ = task_time; | |
299 last_time_ = time; | |
300 return 0; | |
301 } | |
302 | |
303 int64 system_time_delta = task_time - last_system_time_; | |
304 int64 time_delta = time - last_time_; | |
305 DCHECK(time_delta != 0); | |
306 if (time_delta == 0) | |
307 return 0; | |
308 | |
309 // We add time_delta / 2 so the result is rounded. | |
310 int cpu = static_cast<int>((system_time_delta * 100 + time_delta / 2) / | |
311 (time_delta)); | |
312 | |
313 last_system_time_ = task_time; | |
314 last_time_ = time; | |
315 | |
316 return cpu; | |
317 } | |
318 | |
319 mach_port_t ProcessMetrics::TaskForPid(ProcessHandle process) const { | |
320 mach_port_t task = 0; | |
321 if (port_provider_) | |
322 task = port_provider_->TaskForPid(process_); | |
323 if (!task && process_ == getpid()) | |
324 task = mach_task_self(); | |
325 return task; | |
326 } | 215 } |
327 | 216 |
328 // ------------------------------------------------------------------------ | 217 // ------------------------------------------------------------------------ |
329 | 218 |
330 // Bytes committed by the system. | 219 // Bytes committed by the system. |
331 size_t GetSystemCommitCharge() { | 220 size_t GetSystemCommitCharge() { |
332 host_name_port_t host = mach_host_self(); | 221 host_name_port_t host = mach_host_self(); |
333 mach_msg_type_number_t count = HOST_VM_INFO_COUNT; | 222 mach_msg_type_number_t count = HOST_VM_INFO_COUNT; |
334 vm_statistics_data_t data; | 223 vm_statistics_data_t data; |
335 kern_return_t kr = host_statistics(host, HOST_VM_INFO, | 224 kern_return_t kr = host_statistics(host, HOST_VM_INFO, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 CHECK(g_old_malloc && g_old_calloc && g_old_valloc && g_old_realloc) | 321 CHECK(g_old_malloc && g_old_calloc && g_old_valloc && g_old_realloc) |
433 << "Failed to get system allocation functions."; | 322 << "Failed to get system allocation functions."; |
434 | 323 |
435 default_zone->malloc = oom_killer_malloc; | 324 default_zone->malloc = oom_killer_malloc; |
436 default_zone->calloc = oom_killer_calloc; | 325 default_zone->calloc = oom_killer_calloc; |
437 default_zone->valloc = oom_killer_valloc; | 326 default_zone->valloc = oom_killer_valloc; |
438 default_zone->realloc = oom_killer_realloc; | 327 default_zone->realloc = oom_killer_realloc; |
439 } | 328 } |
440 | 329 |
441 } // namespace base | 330 } // namespace base |
OLD | NEW |