1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/process/process_metrics.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker #include <sys/param.h>
10*6777b538SAndroid Build Coastguard Worker #include <sys/sysctl.h>
11*6777b538SAndroid Build Coastguard Worker
12*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/types/expected.h"
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker namespace base {
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker namespace {
18*6777b538SAndroid Build Coastguard Worker
GetProcessCPU(pid_t pid)19*6777b538SAndroid Build Coastguard Worker base::expected<int, ProcessCPUUsageError> GetProcessCPU(pid_t pid) {
20*6777b538SAndroid Build Coastguard Worker struct kinfo_proc info;
21*6777b538SAndroid Build Coastguard Worker size_t length;
22*6777b538SAndroid Build Coastguard Worker int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid,
23*6777b538SAndroid Build Coastguard Worker sizeof(struct kinfo_proc), 0 };
24*6777b538SAndroid Build Coastguard Worker
25*6777b538SAndroid Build Coastguard Worker if (sysctl(mib, std::size(mib), NULL, &length, NULL, 0) < 0) {
26*6777b538SAndroid Build Coastguard Worker return base::unexpected(ProcessCPUUsageError::kSystemError);
27*6777b538SAndroid Build Coastguard Worker }
28*6777b538SAndroid Build Coastguard Worker
29*6777b538SAndroid Build Coastguard Worker mib[5] = (length / sizeof(struct kinfo_proc));
30*6777b538SAndroid Build Coastguard Worker
31*6777b538SAndroid Build Coastguard Worker if (sysctl(mib, std::size(mib), &info, &length, NULL, 0) < 0) {
32*6777b538SAndroid Build Coastguard Worker return base::unexpected(ProcessCPUUsageError::kSystemError);
33*6777b538SAndroid Build Coastguard Worker }
34*6777b538SAndroid Build Coastguard Worker
35*6777b538SAndroid Build Coastguard Worker return base::ok(info.p_pctcpu);
36*6777b538SAndroid Build Coastguard Worker }
37*6777b538SAndroid Build Coastguard Worker
38*6777b538SAndroid Build Coastguard Worker } // namespace
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Worker // static
CreateProcessMetrics(ProcessHandle process)41*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ProcessMetrics> ProcessMetrics::CreateProcessMetrics(
42*6777b538SAndroid Build Coastguard Worker ProcessHandle process) {
43*6777b538SAndroid Build Coastguard Worker return WrapUnique(new ProcessMetrics(process));
44*6777b538SAndroid Build Coastguard Worker }
45*6777b538SAndroid Build Coastguard Worker
46*6777b538SAndroid Build Coastguard Worker base::expected<double, ProcessCPUUsageError>
GetPlatformIndependentCPUUsage()47*6777b538SAndroid Build Coastguard Worker ProcessMetrics::GetPlatformIndependentCPUUsage() {
48*6777b538SAndroid Build Coastguard Worker TimeTicks time = TimeTicks::Now();
49*6777b538SAndroid Build Coastguard Worker
50*6777b538SAndroid Build Coastguard Worker if (last_cpu_time_.is_zero()) {
51*6777b538SAndroid Build Coastguard Worker // First call, just set the last values.
52*6777b538SAndroid Build Coastguard Worker last_cpu_time_ = time;
53*6777b538SAndroid Build Coastguard Worker return base::ok(0.0);
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker const base::expected<int, ProcessCPUUsageError> cpu = GetProcessCPU(process_);
57*6777b538SAndroid Build Coastguard Worker if (!cpu.has_value()) {
58*6777b538SAndroid Build Coastguard Worker return base::unexpected(cpu.error());
59*6777b538SAndroid Build Coastguard Worker }
60*6777b538SAndroid Build Coastguard Worker
61*6777b538SAndroid Build Coastguard Worker last_cpu_time_ = time;
62*6777b538SAndroid Build Coastguard Worker return base::ok(double{cpu.value()} / FSCALE * 100.0);
63*6777b538SAndroid Build Coastguard Worker }
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker base::expected<TimeDelta, ProcessCPUUsageError>
GetCumulativeCPUUsage()66*6777b538SAndroid Build Coastguard Worker ProcessMetrics::GetCumulativeCPUUsage() {
67*6777b538SAndroid Build Coastguard Worker NOTREACHED();
68*6777b538SAndroid Build Coastguard Worker return base::unexpected(ProcessCPUUsageError::kNotImplemented);
69*6777b538SAndroid Build Coastguard Worker }
70*6777b538SAndroid Build Coastguard Worker
ProcessMetrics(ProcessHandle process)71*6777b538SAndroid Build Coastguard Worker ProcessMetrics::ProcessMetrics(ProcessHandle process)
72*6777b538SAndroid Build Coastguard Worker : process_(process),
73*6777b538SAndroid Build Coastguard Worker last_cpu_(0) {}
74*6777b538SAndroid Build Coastguard Worker
GetSystemCommitCharge()75*6777b538SAndroid Build Coastguard Worker size_t GetSystemCommitCharge() {
76*6777b538SAndroid Build Coastguard Worker int mib[] = { CTL_VM, VM_METER };
77*6777b538SAndroid Build Coastguard Worker int pagesize;
78*6777b538SAndroid Build Coastguard Worker struct vmtotal vmtotal;
79*6777b538SAndroid Build Coastguard Worker unsigned long mem_total, mem_free, mem_inactive;
80*6777b538SAndroid Build Coastguard Worker size_t len = sizeof(vmtotal);
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker if (sysctl(mib, std::size(mib), &vmtotal, &len, NULL, 0) < 0)
83*6777b538SAndroid Build Coastguard Worker return 0;
84*6777b538SAndroid Build Coastguard Worker
85*6777b538SAndroid Build Coastguard Worker mem_total = vmtotal.t_vm;
86*6777b538SAndroid Build Coastguard Worker mem_free = vmtotal.t_free;
87*6777b538SAndroid Build Coastguard Worker mem_inactive = vmtotal.t_vm - vmtotal.t_avm;
88*6777b538SAndroid Build Coastguard Worker
89*6777b538SAndroid Build Coastguard Worker pagesize = getpagesize();
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize);
92*6777b538SAndroid Build Coastguard Worker }
93*6777b538SAndroid Build Coastguard Worker
94*6777b538SAndroid Build Coastguard Worker } // namespace base
95