blob: a3b441d7980c49d89b2d9da9a0f17980739222a9 [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 <utility>
#include "base/check.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
namespace base {
namespace {
#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
BUILDFLAG(IS_AIX)
int CalculateEventsPerSecond(uint64_t event_count,
uint64_t* last_event_count,
base::TimeTicks* last_calculated) {
const base::TimeTicks time = base::TimeTicks::Now();
int events_per_second = 0;
if (*last_event_count != 0) {
const uint64_t events_delta = event_count - *last_event_count;
const base::TimeDelta time_delta = time - *last_calculated;
DCHECK(!time_delta.is_zero());
events_per_second = ClampRound(events_delta / time_delta.InSecondsF());
}
*last_calculated = time;
*last_event_count = event_count;
return events_per_second;
}
#endif
} // namespace
SystemMemoryInfoKB::SystemMemoryInfoKB() = default;
SystemMemoryInfoKB::SystemMemoryInfoKB(const SystemMemoryInfoKB&) = default;
SystemMemoryInfoKB& SystemMemoryInfoKB::operator=(const SystemMemoryInfoKB&) =
default;
SystemMetrics::SystemMetrics() {
committed_memory_ = 0;
}
SystemMetrics SystemMetrics::Sample() {
SystemMetrics system_metrics;
system_metrics.committed_memory_ = GetSystemCommitCharge();
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
GetSystemMemoryInfo(&system_metrics.memory_info_);
GetVmStatInfo(&system_metrics.vmstat_info_);
GetSystemDiskInfo(&system_metrics.disk_info_);
#endif
#if BUILDFLAG(IS_CHROMEOS)
GetSwapInfo(&system_metrics.swap_info_);
GetGraphicsMemoryInfo(&system_metrics.gpu_memory_info_);
#endif
#if BUILDFLAG(IS_WIN)
GetSystemPerformanceInfo(&system_metrics.performance_);
#endif
return system_metrics;
}
Value::Dict SystemMetrics::ToDict() const {
Value::Dict res;
res.Set("committed_memory", static_cast<int>(committed_memory_));
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
Value::Dict meminfo = memory_info_.ToDict();
meminfo.Merge(vmstat_info_.ToDict());
res.Set("meminfo", std::move(meminfo));
res.Set("diskinfo", disk_info_.ToDict());
#endif
#if BUILDFLAG(IS_CHROMEOS)
res.Set("swapinfo", swap_info_.ToDict());
res.Set("gpu_meminfo", gpu_memory_info_.ToDict());
#endif
#if BUILDFLAG(IS_WIN)
res.Set("perfinfo", performance_.ToDict());
#endif
return res;
}
ProcessMetrics::~ProcessMetrics() = default;
std::unique_ptr<ProcessMetrics> ProcessMetrics::CreateCurrentProcessMetrics() {
#if !BUILDFLAG(IS_MAC)
return CreateProcessMetrics(base::GetCurrentProcessHandle());
#else
return CreateProcessMetrics(base::GetCurrentProcessHandle(), nullptr);
#endif // !BUILDFLAG(IS_MAC)
}
#if !BUILDFLAG(IS_FREEBSD) || !BUILDFLAG(IS_POSIX)
double ProcessMetrics::GetPlatformIndependentCPUUsage(
TimeDelta cumulative_cpu) {
TimeTicks time = TimeTicks::Now();
if (last_cumulative_cpu_.is_zero()) {
// First call, just set the last values.
last_cumulative_cpu_ = cumulative_cpu;
last_cpu_time_ = time;
return 0;
}
TimeDelta cpu_time_delta = cumulative_cpu - last_cumulative_cpu_;
TimeDelta time_delta = time - last_cpu_time_;
if (time_delta.is_zero())
return 0;
last_cumulative_cpu_ = cumulative_cpu;
last_cpu_time_ = time;
return 100.0 * cpu_time_delta / time_delta;
}
double ProcessMetrics::GetPlatformIndependentCPUUsage() {
return GetPlatformIndependentCPUUsage(GetCumulativeCPUUsage());
}
#endif
#if BUILDFLAG(IS_WIN)
double ProcessMetrics::GetPreciseCPUUsage(TimeDelta cumulative_cpu) {
TimeTicks time = TimeTicks::Now();
if (last_precise_cumulative_cpu_.is_zero()) {
// First call, just set the last values.
last_precise_cumulative_cpu_ = cumulative_cpu;
last_cpu_time_for_precise_cpu_usage_ = time;
return 0;
}
TimeDelta cpu_time_delta = cumulative_cpu - last_precise_cumulative_cpu_;
TimeDelta time_delta = time - last_cpu_time_for_precise_cpu_usage_;
DCHECK(!time_delta.is_zero());
if (time_delta.is_zero())
return 0;
last_precise_cumulative_cpu_ = cumulative_cpu;
last_cpu_time_for_precise_cpu_usage_ = time;
return 100.0 * cpu_time_delta / time_delta;
}
double ProcessMetrics::GetPreciseCPUUsage() {
return GetPreciseCPUUsage(GetPreciseCumulativeCPUUsage());
}
#endif // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
BUILDFLAG(IS_AIX)
int ProcessMetrics::CalculateIdleWakeupsPerSecond(
uint64_t absolute_idle_wakeups) {
return CalculateEventsPerSecond(absolute_idle_wakeups,
&last_absolute_idle_wakeups_,
&last_idle_wakeups_time_);
}
#else
int ProcessMetrics::GetIdleWakeupsPerSecond() {
NOTIMPLEMENTED(); // http://crbug.com/120488
return 0;
}
#endif // BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
// || BUILDFLAG(IS_AIX)
#if BUILDFLAG(IS_APPLE)
int ProcessMetrics::CalculatePackageIdleWakeupsPerSecond(
uint64_t absolute_package_idle_wakeups) {
return CalculateEventsPerSecond(absolute_package_idle_wakeups,
&last_absolute_package_idle_wakeups_,
&last_package_idle_wakeups_time_);
}
#endif // BUILDFLAG(IS_APPLE)
#if !BUILDFLAG(IS_WIN)
uint64_t ProcessMetrics::GetCumulativeDiskUsageInBytes() {
// Not implemented.
return 0;
}
#endif
} // namespace base