• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
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 <sys/param.h>
8 #include <sys/sysctl.h>
9 
10 namespace base {
11 
12 // static
CreateProcessMetrics(ProcessHandle process)13 ProcessMetrics* ProcessMetrics::CreateProcessMetrics(ProcessHandle process) {
14   return new ProcessMetrics(process);
15 }
16 
GetPagefileUsage() const17 size_t ProcessMetrics::GetPagefileUsage() const {
18   struct kinfo_proc info;
19   size_t length;
20   int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_,
21                 sizeof(struct kinfo_proc), 0 };
22 
23   if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
24     return -1;
25 
26   mib[5] = (length / sizeof(struct kinfo_proc));
27 
28   if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
29     return -1;
30 
31   return (info.p_vm_tsize + info.p_vm_dsize + info.p_vm_ssize);
32 }
33 
GetPeakPagefileUsage() const34 size_t ProcessMetrics::GetPeakPagefileUsage() const {
35   return 0;
36 }
37 
GetWorkingSetSize() const38 size_t ProcessMetrics::GetWorkingSetSize() const {
39   struct kinfo_proc info;
40   size_t length;
41   int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, process_,
42                 sizeof(struct kinfo_proc), 0 };
43 
44   if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
45     return -1;
46 
47   mib[5] = (length / sizeof(struct kinfo_proc));
48 
49   if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
50     return -1;
51 
52   return info.p_vm_rssize * getpagesize();
53 }
54 
GetPeakWorkingSetSize() const55 size_t ProcessMetrics::GetPeakWorkingSetSize() const {
56   return 0;
57 }
58 
GetMemoryBytes(size_t * private_bytes,size_t * shared_bytes)59 bool ProcessMetrics::GetMemoryBytes(size_t* private_bytes,
60                                     size_t* shared_bytes) {
61   WorkingSetKBytes ws_usage;
62 
63   if (!GetWorkingSetKBytes(&ws_usage))
64     return false;
65 
66   if (private_bytes)
67     *private_bytes = ws_usage.priv << 10;
68 
69   if (shared_bytes)
70     *shared_bytes = ws_usage.shared * 1024;
71 
72   return true;
73 }
74 
GetWorkingSetKBytes(WorkingSetKBytes * ws_usage) const75 bool ProcessMetrics::GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const {
76   // TODO(bapt): be sure we can't be precise
77   size_t priv = GetWorkingSetSize();
78   if (!priv)
79     return false;
80   ws_usage->priv = priv / 1024;
81   ws_usage->shareable = 0;
82   ws_usage->shared = 0;
83 
84   return true;
85 }
86 
GetIOCounters(IoCounters * io_counters) const87 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) const {
88   return false;
89 }
90 
GetProcessCPU(pid_t pid)91 static int GetProcessCPU(pid_t pid) {
92   struct kinfo_proc info;
93   size_t length;
94   int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid,
95                 sizeof(struct kinfo_proc), 0 };
96 
97   if (sysctl(mib, arraysize(mib), NULL, &length, NULL, 0) < 0)
98     return -1;
99 
100   mib[5] = (length / sizeof(struct kinfo_proc));
101 
102   if (sysctl(mib, arraysize(mib), &info, &length, NULL, 0) < 0)
103     return 0;
104 
105   return info.p_pctcpu;
106 }
107 
GetCPUUsage()108 double ProcessMetrics::GetCPUUsage() {
109   struct timeval now;
110 
111   int retval = gettimeofday(&now, NULL);
112   if (retval)
113     return 0;
114 
115   int64 time = TimeValToMicroseconds(now);
116 
117   if (last_time_ == 0) {
118     // First call, just set the last values.
119     last_time_ = time;
120     last_cpu_ = GetProcessCPU(process_);
121     return 0;
122   }
123 
124   int64 time_delta = time - last_time_;
125   DCHECK_NE(time_delta, 0);
126 
127   if (time_delta == 0)
128     return 0;
129 
130   int cpu = GetProcessCPU(process_);
131 
132   last_time_ = time;
133   last_cpu_ = cpu;
134 
135   double percentage = static_cast<double>((cpu * 100.0) / FSCALE);
136 
137   return percentage;
138 }
139 
ProcessMetrics(ProcessHandle process)140 ProcessMetrics::ProcessMetrics(ProcessHandle process)
141     : process_(process),
142       last_time_(0),
143       last_system_time_(0),
144       last_cpu_(0) {
145 
146   processor_count_ = base::SysInfo::NumberOfProcessors();
147 }
148 
GetSystemCommitCharge()149 size_t GetSystemCommitCharge() {
150   int mib[] = { CTL_VM, VM_METER };
151   int pagesize;
152   struct vmtotal vmtotal;
153   unsigned long mem_total, mem_free, mem_inactive;
154   size_t len = sizeof(vmtotal);
155 
156   if (sysctl(mib, arraysize(mib), &vmtotal, &len, NULL, 0) < 0)
157     return 0;
158 
159   mem_total = vmtotal.t_vm;
160   mem_free = vmtotal.t_free;
161   mem_inactive = vmtotal.t_vm - vmtotal.t_avm;
162 
163   pagesize = getpagesize();
164 
165   return mem_total - (mem_free*pagesize) - (mem_inactive*pagesize);
166 }
167 
168 }  // namespace base
169