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