blob: 9b49a58534fb717a290cde431b029eef2a047b32 [file] [log] [blame]
// 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