1 // Copyright 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 <utility>
8 
9 #include "base/logging.h"
10 #include "base/values.h"
11 #include "build/build_config.h"
12 
13 #if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_AIX)
14 namespace {
CalculateEventsPerSecond(uint64_t event_count,uint64_t * last_event_count,base::TimeTicks * last_calculated)15 int CalculateEventsPerSecond(uint64_t event_count,
16                              uint64_t* last_event_count,
17                              base::TimeTicks* last_calculated) {
18   base::TimeTicks time = base::TimeTicks::Now();
19 
20   if (*last_event_count == 0) {
21     // First call, just set the last values.
22     *last_calculated = time;
23     *last_event_count = event_count;
24     return 0;
25   }
26 
27   int64_t events_delta = event_count - *last_event_count;
28   int64_t time_delta = (time - *last_calculated).InMicroseconds();
29   if (time_delta == 0) {
30     NOTREACHED();
31     return 0;
32   }
33 
34   *last_calculated = time;
35   *last_event_count = event_count;
36 
37   int64_t events_delta_for_ms =
38       events_delta * base::Time::kMicrosecondsPerSecond;
39   // Round the result up by adding 1/2 (the second term resolves to 1/2 without
40   // dropping down into floating point).
41   return (events_delta_for_ms + time_delta / 2) / time_delta;
42 }
43 
44 }  // namespace
45 #endif  // defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_AIX)
46 
47 namespace base {
48 
49 SystemMemoryInfoKB::SystemMemoryInfoKB() = default;
50 
51 SystemMemoryInfoKB::SystemMemoryInfoKB(const SystemMemoryInfoKB& other) =
52     default;
53 
SystemMetrics()54 SystemMetrics::SystemMetrics() {
55   committed_memory_ = 0;
56 }
57 
Sample()58 SystemMetrics SystemMetrics::Sample() {
59   SystemMetrics system_metrics;
60 
61   system_metrics.committed_memory_ = GetSystemCommitCharge();
62 #if defined(OS_LINUX) || defined(OS_ANDROID)
63   GetSystemMemoryInfo(&system_metrics.memory_info_);
64   GetVmStatInfo(&system_metrics.vmstat_info_);
65   GetSystemDiskInfo(&system_metrics.disk_info_);
66 #endif
67 #if defined(OS_CHROMEOS)
68   GetSwapInfo(&system_metrics.swap_info_);
69 #endif
70 
71   return system_metrics;
72 }
73 
ToValue() const74 std::unique_ptr<Value> SystemMetrics::ToValue() const {
75   std::unique_ptr<DictionaryValue> res(new DictionaryValue());
76 
77   res->SetInteger("committed_memory", static_cast<int>(committed_memory_));
78 #if defined(OS_LINUX) || defined(OS_ANDROID)
79   std::unique_ptr<DictionaryValue> meminfo = memory_info_.ToValue();
80   std::unique_ptr<DictionaryValue> vmstat = vmstat_info_.ToValue();
81   meminfo->MergeDictionary(vmstat.get());
82   res->Set("meminfo", std::move(meminfo));
83   res->Set("diskinfo", disk_info_.ToValue());
84 #endif
85 #if defined(OS_CHROMEOS)
86   res->Set("swapinfo", swap_info_.ToValue());
87 #endif
88 
89   return std::move(res);
90 }
91 
CreateCurrentProcessMetrics()92 std::unique_ptr<ProcessMetrics> ProcessMetrics::CreateCurrentProcessMetrics() {
93 #if !defined(OS_MACOSX) || defined(OS_IOS)
94   return CreateProcessMetrics(base::GetCurrentProcessHandle());
95 #else
96   return CreateProcessMetrics(base::GetCurrentProcessHandle(), nullptr);
97 #endif  // !defined(OS_MACOSX) || defined(OS_IOS)
98 }
99 
100 #if !defined(OS_FREEBSD) || !defined(OS_POSIX)
GetPlatformIndependentCPUUsage()101 double ProcessMetrics::GetPlatformIndependentCPUUsage() {
102   TimeDelta cumulative_cpu = GetCumulativeCPUUsage();
103   TimeTicks time = TimeTicks::Now();
104 
105   if (last_cumulative_cpu_.is_zero()) {
106     // First call, just set the last values.
107     last_cumulative_cpu_ = cumulative_cpu;
108     last_cpu_time_ = time;
109     return 0;
110   }
111 
112   TimeDelta system_time_delta = cumulative_cpu - last_cumulative_cpu_;
113   TimeDelta time_delta = time - last_cpu_time_;
114   DCHECK(!time_delta.is_zero());
115   if (time_delta.is_zero())
116     return 0;
117 
118   last_cumulative_cpu_ = cumulative_cpu;
119   last_cpu_time_ = time;
120 
121   return 100.0 * system_time_delta.InMicrosecondsF() /
122          time_delta.InMicrosecondsF();
123 }
124 #endif
125 
126 #if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_AIX)
CalculateIdleWakeupsPerSecond(uint64_t absolute_idle_wakeups)127 int ProcessMetrics::CalculateIdleWakeupsPerSecond(
128     uint64_t absolute_idle_wakeups) {
129   return CalculateEventsPerSecond(absolute_idle_wakeups,
130                                   &last_absolute_idle_wakeups_,
131                                   &last_idle_wakeups_time_);
132 }
133 #else
GetIdleWakeupsPerSecond()134 int ProcessMetrics::GetIdleWakeupsPerSecond() {
135   NOTIMPLEMENTED();  // http://crbug.com/120488
136   return 0;
137 }
138 #endif  // defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_AIX)
139 
140 #if defined(OS_MACOSX)
CalculatePackageIdleWakeupsPerSecond(uint64_t absolute_package_idle_wakeups)141 int ProcessMetrics::CalculatePackageIdleWakeupsPerSecond(
142     uint64_t absolute_package_idle_wakeups) {
143   return CalculateEventsPerSecond(absolute_package_idle_wakeups,
144                                   &last_absolute_package_idle_wakeups_,
145                                   &last_package_idle_wakeups_time_);
146 }
147 
148 #endif  // defined(OS_MACOSX)
149 }  // namespace base
150