Chromium Code Reviews| 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 // Mac doesn't have /proc, and getting a mach task from a pid for another | 185 // Getting a mach task from a pid for another process requires permissions in |
| 186 // process requires permissions, so there doesn't really seem to be a way | 186 // general, so there doesn't really seem to be a way to do these (and spinning |
|
Mark Mentovai
2009/12/18 22:18:24
Revise this. The parenthetical never ends.
Nico
2009/12/18 22:46:52
Done.
| |
| 187 // to do these (and spinning up ps to fetch each stats seems dangerous to | 187 // up ps to fetch each stats seems dangerous to put in a base api for anyone to |
| 188 // put in a base api for anyone to call. | 188 // call. Child processes ipc their port, so return something if available, else |
|
Mark Mentovai
2009/12/18 22:18:24
When speaking English, "otherwise" is friendlier t
Nico
2009/12/18 22:46:52
Done.
kexinli365
2016/05/08 01:09:31
Acknowledged.
| |
| 189 // return 0. | |
| 189 // | 190 // |
| 190 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { | 191 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { |
| 191 return false; | 192 return false; |
| 192 } | 193 } |
| 194 | |
| 193 size_t ProcessMetrics::GetPagefileUsage() const { | 195 size_t ProcessMetrics::GetPagefileUsage() const { |
| 194 return 0; | 196 mach_port_t task = TaskForPid(process_); |
|
Mark Mentovai
2009/12/18 22:18:24
D'ya need to check if task exists? You do that ch
Nico
2009/12/18 22:46:52
Done.
| |
| 197 task_basic_info_64 task_info_data; | |
| 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 (task_info_t)&task_info_data, | |
|
Mark Mentovai
2009/12/18 22:18:24
Prefer C++<style>(casts) unless you need to chain
Nico
2009/12/18 22:46:52
Done.
| |
| 202 &count); | |
| 203 if (kr != KERN_SUCCESS) { | |
| 204 // Most likely cause: |task| is a zombie. | |
| 205 return 0; | |
| 206 } | |
| 207 return task_info_data.virtual_size; | |
| 195 } | 208 } |
| 209 | |
| 196 size_t ProcessMetrics::GetPeakPagefileUsage() const { | 210 size_t ProcessMetrics::GetPeakPagefileUsage() const { |
| 197 return 0; | 211 return 0; |
| 198 } | 212 } |
| 213 | |
| 199 size_t ProcessMetrics::GetWorkingSetSize() const { | 214 size_t ProcessMetrics::GetWorkingSetSize() const { |
| 200 return 0; | 215 mach_port_t task = TaskForPid(process_); |
| 216 task_basic_info_64 task_info_data; | |
| 217 mach_msg_type_number_t count = TASK_BASIC_INFO_64_COUNT; | |
| 218 kern_return_t kr = task_info(task, | |
|
Mark Mentovai
2009/12/18 22:18:24
Refactor into a common function to populate a task
Nico
2009/12/18 22:46:52
Done.
kexinli365
2016/05/08 01:09:31
Done.
| |
| 219 TASK_BASIC_INFO_64, | |
| 220 (task_info_t)&task_info_data, | |
| 221 &count); | |
| 222 if (kr != KERN_SUCCESS) { | |
| 223 // Most likely cause: |task| is a zombie. | |
| 224 return 0; | |
| 225 } | |
| 226 return task_info_data.resident_size; | |
| 201 } | 227 } |
| 228 | |
| 202 size_t ProcessMetrics::GetPeakWorkingSetSize() const { | 229 size_t ProcessMetrics::GetPeakWorkingSetSize() const { |
| 203 return 0; | 230 return 0; |
| 204 } | 231 } |
| 205 | 232 |
| 206 size_t ProcessMetrics::GetPrivateBytes() const { | 233 size_t ProcessMetrics::GetPrivateBytes() const { |
| 207 return 0; | 234 return 0; |
| 208 } | 235 } |
| 209 | 236 |
| 210 void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const { | 237 void ProcessMetrics::GetCommittedKBytes(CommittedKBytes* usage) const { |
| 211 } | 238 } |
| 212 | 239 |
| 213 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { | 240 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const { |
| 214 return false; | 241 size_t priv = GetWorkingSetSize(); |
| 242 if (!priv) | |
| 243 return false; | |
| 244 ws_usage->priv = priv / 1024; | |
| 245 ws_usage->shareable = 0; | |
| 246 ws_usage->shared = 0; | |
| 247 return true; | |
| 248 } | |
| 249 | |
| 250 #define TIME_VALUE_TO_TIMEVAL(a, r) do { \ | |
| 251 (r)->tv_sec = (a)->seconds; \ | |
| 252 (r)->tv_usec = (a)->microseconds; \ | |
| 253 } while (0) | |
| 254 | |
| 255 int ProcessMetrics::GetCPUUsage() { | |
| 256 mach_port_t task = TaskForPid(process_); | |
| 257 if (!task) { | |
| 258 // Most likely cause: |task| is a zombie. | |
| 259 return 0; | |
| 260 } | |
| 261 | |
| 262 kern_return_t kr; | |
| 263 | |
| 264 // TODO(thakis): Libtop doesn't use thread info. How can they get away | |
| 265 // without it? | |
| 266 task_thread_times_info thread_info_data; | |
| 267 mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT; | |
| 268 kr = task_info(task, | |
| 269 TASK_THREAD_TIMES_INFO, | |
| 270 (task_info_t)&thread_info_data, | |
|
Mark Mentovai
2009/12/18 22:18:24
C++-style cast again.
Nico
2009/12/18 22:46:52
Done.
| |
| 271 &thread_info_count); | |
| 272 if (kr != KERN_SUCCESS) { | |
| 273 LOG(ERROR) << "Failed to get thread info for task" << task; | |
|
Mark Mentovai
2009/12/18 22:18:24
You need a space at the end of your string literal
Nico
2009/12/18 22:46:52
Done.
| |
| 274 return 0; | |
| 275 } | |
| 276 | |
| 277 task_basic_info_64 task_info_data; | |
| 278 mach_msg_type_number_t task_basic_info_count = TASK_BASIC_INFO_64_COUNT; | |
| 279 kr = task_info(task, | |
| 280 TASK_BASIC_INFO_64, | |
| 281 (task_info_t)&task_info_data, | |
| 282 &task_basic_info_count); | |
| 283 if (kr != KERN_SUCCESS) { | |
| 284 LOG(ERROR) << "Failed to get task info for task" << task; | |
| 285 return 0; | |
| 286 } | |
| 287 | |
| 288 /* Set total_time. */ | |
| 289 // thread info contains live time... | |
| 290 struct timeval user_timeval, system_timeval, task_timeval; | |
| 291 TIME_VALUE_TO_TIMEVAL(&thread_info_data.user_time, &user_timeval); | |
| 292 TIME_VALUE_TO_TIMEVAL(&thread_info_data.system_time, &system_timeval); | |
| 293 timeradd(&user_timeval, &system_timeval, &task_timeval); | |
| 294 | |
| 295 // ... task info contains terminated time. | |
| 296 TIME_VALUE_TO_TIMEVAL(&task_info_data.user_time, &user_timeval); | |
| 297 TIME_VALUE_TO_TIMEVAL(&task_info_data.system_time, &system_timeval); | |
| 298 timeradd(&user_timeval, &task_timeval, &task_timeval); | |
| 299 timeradd(&system_timeval, &task_timeval, &task_timeval); | |
| 300 | |
| 301 struct timeval now; | |
| 302 int retval = gettimeofday(&now, NULL); | |
| 303 if (retval) | |
| 304 return 0; | |
| 305 | |
| 306 int64 time = TimeValToMicroseconds(now); | |
| 307 int64 task_time = TimeValToMicroseconds(task_timeval); | |
| 308 | |
| 309 if ((last_system_time_ == 0) || (last_time_ == 0)) { | |
| 310 // First call, just set the last values. | |
| 311 last_system_time_ = task_time; | |
| 312 last_time_ = time; | |
| 313 return 0; | |
| 314 } | |
| 315 | |
| 316 int64 system_time_delta = task_time - last_system_time_; | |
| 317 int64 time_delta = time - last_time_; | |
| 318 DCHECK(time_delta != 0); | |
| 319 if (time_delta == 0) | |
| 320 return 0; | |
| 321 | |
| 322 // We add time_delta / 2 so the result is rounded. | |
| 323 int cpu = static_cast<int>((system_time_delta * 100 + time_delta / 2) / | |
| 324 (time_delta)); | |
| 325 | |
| 326 last_system_time_ = task_time; | |
| 327 last_time_ = time; | |
| 328 | |
| 329 return cpu; | |
| 330 } | |
| 331 | |
| 332 mach_port_t ProcessMetrics::TaskForPid(ProcessHandle process) const { | |
| 333 mach_port_t task = 0; | |
| 334 if (port_provider_) | |
| 335 task = port_provider_->TaskForPid(process_); | |
| 336 if (!task && process_ == getpid()) | |
| 337 task = mach_task_self(); | |
| 338 return task; | |
| 215 } | 339 } |
| 216 | 340 |
| 217 // ------------------------------------------------------------------------ | 341 // ------------------------------------------------------------------------ |
| 218 | 342 |
| 219 // Bytes committed by the system. | 343 // Bytes committed by the system. |
| 220 size_t GetSystemCommitCharge() { | 344 size_t GetSystemCommitCharge() { |
| 221 host_name_port_t host = mach_host_self(); | 345 host_name_port_t host = mach_host_self(); |
| 222 mach_msg_type_number_t count = HOST_VM_INFO_COUNT; | 346 mach_msg_type_number_t count = HOST_VM_INFO_COUNT; |
| 223 vm_statistics_data_t data; | 347 vm_statistics_data_t data; |
| 224 kern_return_t kr = host_statistics(host, HOST_VM_INFO, | 348 kern_return_t kr = host_statistics(host, HOST_VM_INFO, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 321 CHECK(g_old_malloc && g_old_calloc && g_old_valloc && g_old_realloc) | 445 CHECK(g_old_malloc && g_old_calloc && g_old_valloc && g_old_realloc) |
| 322 << "Failed to get system allocation functions."; | 446 << "Failed to get system allocation functions."; |
| 323 | 447 |
| 324 default_zone->malloc = oom_killer_malloc; | 448 default_zone->malloc = oom_killer_malloc; |
| 325 default_zone->calloc = oom_killer_calloc; | 449 default_zone->calloc = oom_killer_calloc; |
| 326 default_zone->valloc = oom_killer_valloc; | 450 default_zone->valloc = oom_killer_valloc; |
| 327 default_zone->realloc = oom_killer_realloc; | 451 default_zone->realloc = oom_killer_realloc; |
| 328 } | 452 } |
| 329 | 453 |
| 330 } // namespace base | 454 } // namespace base |
| OLD | NEW |