• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <utility>
8 
9 #include "base/check.h"
10 #include "base/notreached.h"
11 #include "base/numerics/safe_conversions.h"
12 #include "base/values.h"
13 #include "build/build_config.h"
14 
15 namespace base {
16 
17 namespace {
18 
19 #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
20     BUILDFLAG(IS_AIX)
CalculateEventsPerSecond(uint64_t event_count,uint64_t * last_event_count,base::TimeTicks * last_calculated)21 int CalculateEventsPerSecond(uint64_t event_count,
22                              uint64_t* last_event_count,
23                              base::TimeTicks* last_calculated) {
24   const base::TimeTicks time = base::TimeTicks::Now();
25 
26   int events_per_second = 0;
27   if (*last_event_count != 0) {
28     const uint64_t events_delta = event_count - *last_event_count;
29     const base::TimeDelta time_delta = time - *last_calculated;
30     DCHECK(!time_delta.is_zero());
31     events_per_second = ClampRound(events_delta / time_delta.InSecondsF());
32   }
33 
34   *last_calculated = time;
35   *last_event_count = event_count;
36   return events_per_second;
37 }
38 #endif
39 
40 }  // namespace
41 
42 SystemMemoryInfoKB::SystemMemoryInfoKB() = default;
43 
44 SystemMemoryInfoKB::SystemMemoryInfoKB(const SystemMemoryInfoKB&) = default;
45 
46 SystemMemoryInfoKB& SystemMemoryInfoKB::operator=(const SystemMemoryInfoKB&) =
47     default;
48 
SystemMetrics()49 SystemMetrics::SystemMetrics() {
50   committed_memory_ = 0;
51 }
52 
Sample()53 SystemMetrics SystemMetrics::Sample() {
54   SystemMetrics system_metrics;
55 
56   system_metrics.committed_memory_ = GetSystemCommitCharge();
57 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
58   GetSystemMemoryInfo(&system_metrics.memory_info_);
59   GetVmStatInfo(&system_metrics.vmstat_info_);
60   GetSystemDiskInfo(&system_metrics.disk_info_);
61 #endif
62 #if BUILDFLAG(IS_CHROMEOS)
63   GetSwapInfo(&system_metrics.swap_info_);
64   GetGraphicsMemoryInfo(&system_metrics.gpu_memory_info_);
65 #endif
66 #if BUILDFLAG(IS_WIN)
67   GetSystemPerformanceInfo(&system_metrics.performance_);
68 #endif
69   return system_metrics;
70 }
71 
ToDict() const72 Value::Dict SystemMetrics::ToDict() const {
73   Value::Dict res;
74 
75   res.Set("committed_memory", static_cast<int>(committed_memory_));
76 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
77   Value::Dict meminfo = memory_info_.ToDict();
78   meminfo.Merge(vmstat_info_.ToDict());
79   res.Set("meminfo", std::move(meminfo));
80   res.Set("diskinfo", disk_info_.ToDict());
81 #endif
82 #if BUILDFLAG(IS_CHROMEOS)
83   res.Set("swapinfo", swap_info_.ToDict());
84   res.Set("gpu_meminfo", gpu_memory_info_.ToDict());
85 #endif
86 #if BUILDFLAG(IS_WIN)
87   res.Set("perfinfo", performance_.ToDict());
88 #endif
89 
90   return res;
91 }
92 
93 ProcessMetrics::~ProcessMetrics() = default;
94 
CreateCurrentProcessMetrics()95 std::unique_ptr<ProcessMetrics> ProcessMetrics::CreateCurrentProcessMetrics() {
96 #if !BUILDFLAG(IS_MAC)
97   return CreateProcessMetrics(base::GetCurrentProcessHandle());
98 #else
99   return CreateProcessMetrics(base::GetCurrentProcessHandle(), nullptr);
100 #endif  // !BUILDFLAG(IS_MAC)
101 }
102 
103 #if !BUILDFLAG(IS_FREEBSD) || !BUILDFLAG(IS_POSIX)
GetPlatformIndependentCPUUsage(TimeDelta cumulative_cpu)104 double ProcessMetrics::GetPlatformIndependentCPUUsage(
105     TimeDelta cumulative_cpu) {
106   TimeTicks time = TimeTicks::Now();
107 
108   if (last_cumulative_cpu_.is_zero()) {
109     // First call, just set the last values.
110     last_cumulative_cpu_ = cumulative_cpu;
111     last_cpu_time_ = time;
112     return 0;
113   }
114 
115   TimeDelta cpu_time_delta = cumulative_cpu - last_cumulative_cpu_;
116   TimeDelta time_delta = time - last_cpu_time_;
117   if (time_delta.is_zero())
118     return 0;
119 
120   last_cumulative_cpu_ = cumulative_cpu;
121   last_cpu_time_ = time;
122 
123   return 100.0 * cpu_time_delta / time_delta;
124 }
125 
GetPlatformIndependentCPUUsage()126 double ProcessMetrics::GetPlatformIndependentCPUUsage() {
127   return GetPlatformIndependentCPUUsage(GetCumulativeCPUUsage());
128 }
129 #endif
130 
131 #if BUILDFLAG(IS_WIN)
GetPreciseCPUUsage(TimeDelta cumulative_cpu)132 double ProcessMetrics::GetPreciseCPUUsage(TimeDelta cumulative_cpu) {
133   TimeTicks time = TimeTicks::Now();
134 
135   if (last_precise_cumulative_cpu_.is_zero()) {
136     // First call, just set the last values.
137     last_precise_cumulative_cpu_ = cumulative_cpu;
138     last_cpu_time_for_precise_cpu_usage_ = time;
139     return 0;
140   }
141 
142   TimeDelta cpu_time_delta = cumulative_cpu - last_precise_cumulative_cpu_;
143   TimeDelta time_delta = time - last_cpu_time_for_precise_cpu_usage_;
144   DCHECK(!time_delta.is_zero());
145   if (time_delta.is_zero())
146     return 0;
147 
148   last_precise_cumulative_cpu_ = cumulative_cpu;
149   last_cpu_time_for_precise_cpu_usage_ = time;
150 
151   return 100.0 * cpu_time_delta / time_delta;
152 }
153 
GetPreciseCPUUsage()154 double ProcessMetrics::GetPreciseCPUUsage() {
155   return GetPreciseCPUUsage(GetPreciseCumulativeCPUUsage());
156 }
157 #endif  // BUILDFLAG(IS_WIN)
158 
159 #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
160     BUILDFLAG(IS_AIX)
CalculateIdleWakeupsPerSecond(uint64_t absolute_idle_wakeups)161 int ProcessMetrics::CalculateIdleWakeupsPerSecond(
162     uint64_t absolute_idle_wakeups) {
163   return CalculateEventsPerSecond(absolute_idle_wakeups,
164                                   &last_absolute_idle_wakeups_,
165                                   &last_idle_wakeups_time_);
166 }
167 #else
GetIdleWakeupsPerSecond()168 int ProcessMetrics::GetIdleWakeupsPerSecond() {
169   NOTIMPLEMENTED();  // http://crbug.com/120488
170   return 0;
171 }
172 #endif  // BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
173         // || BUILDFLAG(IS_AIX)
174 
175 #if BUILDFLAG(IS_APPLE)
CalculatePackageIdleWakeupsPerSecond(uint64_t absolute_package_idle_wakeups)176 int ProcessMetrics::CalculatePackageIdleWakeupsPerSecond(
177     uint64_t absolute_package_idle_wakeups) {
178   return CalculateEventsPerSecond(absolute_package_idle_wakeups,
179                                   &last_absolute_package_idle_wakeups_,
180                                   &last_package_idle_wakeups_time_);
181 }
182 
183 #endif  // BUILDFLAG(IS_APPLE)
184 
185 #if !BUILDFLAG(IS_WIN)
GetCumulativeDiskUsageInBytes()186 uint64_t ProcessMetrics::GetCumulativeDiskUsageInBytes() {
187   // Not implemented.
188   return 0;
189 }
190 #endif
191 
192 }  // namespace base
193