| // Copyright 2013 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/process/process_metrics.h" |
| |
| #include <AvailabilityMacros.h> |
| #include <libproc.h> |
| #include <mach/mach.h> |
| #include <mach/mach_time.h> |
| #include <mach/mach_vm.h> |
| #include <mach/shared_region.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| #include <sys/sysctl.h> |
| #include <memory> |
| |
| #include "base/logging.h" |
| #include "base/mac/mac_util.h" |
| #include "base/mac/mach_logging.h" |
| #include "base/mac/scoped_mach_port.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/numerics/safe_conversions.h" |
| #include "base/numerics/safe_math.h" |
| #include "base/process/process_metrics_iocounters.h" |
| #include "base/time/time.h" |
| #include "build/build_config.h" |
| #include "process_metrics_apple_internal.h" |
| |
| namespace base { |
| |
| // Getting a mach task from a pid for another process requires permissions in |
| // general, so there doesn't really seem to be a way to do these (and spinning |
| // up ps to fetch each stats seems dangerous to put in a base api for anyone to |
| // call). Child processes ipc their port, so return something if available, |
| // otherwise return 0. |
| |
| // static |
| std::unique_ptr<ProcessMetrics> ProcessMetrics::CreateProcessMetrics( |
| ProcessHandle process, |
| PortProvider* port_provider) { |
| return WrapUnique(new ProcessMetrics(process, port_provider)); |
| } |
| |
| ProcessMetrics::ProcessMetrics(ProcessHandle process, |
| PortProvider* port_provider) |
| : last_absolute_idle_wakeups_(0), last_absolute_package_idle_wakeups_(0) { |
| process_metrics_helper_ = |
| std::make_unique<ProcessMetricsAppleInternal>(process, port_provider); |
| } |
| |
| TimeDelta ProcessMetrics::GetCumulativeCPUUsage() { |
| return process_metrics_helper_->GetCumulativeCPUUsage(); |
| } |
| |
| int ProcessMetrics::GetPackageIdleWakeupsPerSecond() { |
| task_power_info power_info_data = process_metrics_helper_->GetTaskPowerInfo(); |
| |
| // The task_power_info struct contains two wakeup counters: |
| // task_interrupt_wakeups and task_platform_idle_wakeups. |
| // task_interrupt_wakeups is the total number of wakeups generated by the |
| // process, and is the number that Activity Monitor reports. |
| // task_platform_idle_wakeups is a subset of task_interrupt_wakeups that |
| // tallies the number of times the processor was taken out of its low-power |
| // idle state to handle a wakeup. task_platform_idle_wakeups therefore result |
| // in a greater power increase than the other interrupts which occur while the |
| // CPU is already working, and reducing them has a greater overall impact on |
| // power usage. See the powermetrics man page for more info. |
| return CalculatePackageIdleWakeupsPerSecond( |
| power_info_data.task_platform_idle_wakeups); |
| } |
| |
| int ProcessMetrics::GetIdleWakeupsPerSecond() { |
| task_power_info power_info_data = process_metrics_helper_->GetTaskPowerInfo(); |
| |
| return CalculateIdleWakeupsPerSecond(power_info_data.task_interrupt_wakeups); |
| } |
| |
| int ProcessMetrics::GetEnergyImpact() { |
| return process_metrics_helper_->GetEnergyImpact(); |
| } |
| |
| int ProcessMetrics::GetOpenFdCount() const { |
| return process_metrics_helper_->GetOpenFdCount(); |
| } |
| |
| int ProcessMetrics::GetOpenFdSoftLimit() const { |
| return process_metrics_helper_->GetOpenFdSoftLimit(); |
| } |
| |
| bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const { |
| return false; |
| } |
| |
| } // namespace base |