| Avi Drissman | e4622aa | 2022-09-08 20:36:06 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | // This file contains routines for gathering resource statistics for processes |
| 6 | // running on the system. |
| 7 | |
| 8 | #ifndef BASE_PROCESS_PROCESS_METRICS_H_ |
| 9 | #define BASE_PROCESS_PROCESS_METRICS_H_ |
| 10 | |
| avi | beced7c | 2015-12-24 06:47:59 | [diff] [blame] | 11 | #include <stddef.h> |
| 12 | #include <stdint.h> |
| 13 | |
| thestig | 0df2bae8 | 2016-07-26 17:59:36 | [diff] [blame] | 14 | #include <memory> |
| Helmut Januschka | bfa62f7 | 2024-04-04 15:18:31 | [diff] [blame] | 15 | #include <string_view> |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 16 | |
| 17 | #include "base/base_export.h" |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 18 | #include "base/byte_count.h" |
| Alex Attar | d42f011 | 2025-11-13 20:03:57 | [diff] [blame] | 19 | #include "base/byte_size.h" |
| [email protected] | 669a0933 | 2013-08-30 22:59:14 | [diff] [blame] | 20 | #include "base/gtest_prod_util.h" |
| Keishi Hattori | 7c3c718 | 2022-06-24 22:18:14 | [diff] [blame] | 21 | #include "base/memory/raw_ptr.h" |
| [email protected] | dd4b5126 | 2013-07-25 21:38:23 | [diff] [blame] | 22 | #include "base/process/process_handle.h" |
| [email protected] | 8f9a3a5 | 2013-06-28 15:14:18 | [diff] [blame] | 23 | #include "base/time/time.h" |
| Joe Mason | 550eed6 | 2024-03-25 18:07:31 | [diff] [blame] | 24 | #include "base/types/expected.h" |
| Roman Sorokin | a8cf50eb6 | 2023-01-18 11:22:26 | [diff] [blame] | 25 | #include "base/values.h" |
| avi | beced7c | 2015-12-24 06:47:59 | [diff] [blame] | 26 | #include "build/build_config.h" |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 27 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 28 | #if BUILDFLAG(IS_APPLE) |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 29 | #include <mach/mach.h> |
| Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 30 | |
| erikchen | cd3e0e7b | 2015-10-01 22:53:51 | [diff] [blame] | 31 | #include "base/process/port_provider_mac.h" |
| erikchen | 12531f2 | 2017-04-21 19:48:51 | [diff] [blame] | 32 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 33 | #if !BUILDFLAG(IS_IOS) |
| erikchen | 12531f2 | 2017-04-21 19:48:51 | [diff] [blame] | 34 | #include <mach/mach_vm.h> |
| 35 | #endif |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 36 | #endif |
| 37 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 38 | #if BUILDFLAG(IS_WIN) |
| stanisc | e73f1a4 | 2017-03-31 21:42:22 | [diff] [blame] | 39 | #include "base/win/scoped_handle.h" |
| Bruce Dawson | bfdc3fd | 2018-01-03 20:32:36 | [diff] [blame] | 40 | #include "base/win/windows_types.h" |
| stanisc | e73f1a4 | 2017-03-31 21:42:22 | [diff] [blame] | 41 | #endif |
| 42 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 43 | #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ |
| 44 | BUILDFLAG(IS_AIX) |
| Lei Zhang | aecb6ff6 | 2021-05-14 20:23:36 | [diff] [blame] | 45 | #include <string> |
| 46 | #include <utility> |
| 47 | #include <vector> |
| 48 | |
| Lei Zhang | aecb6ff6 | 2021-05-14 20:23:36 | [diff] [blame] | 49 | #include "base/threading/platform_thread.h" |
| 50 | #endif |
| 51 | |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 52 | namespace base { |
| 53 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 54 | #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) |
| Benoit Lize | 448ee88 | 2017-08-31 13:32:12 | [diff] [blame] | 55 | // Minor and major page fault counts since the process creation. |
| 56 | // Both counts are process-wide, and exclude child processes. |
| 57 | // |
| 58 | // minor: Number of page faults that didn't require disk IO. |
| 59 | // major: Number of page faults that required disk IO. |
| 60 | struct PageFaultCounts { |
| 61 | int64_t minor; |
| 62 | int64_t major; |
| 63 | }; |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 64 | #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || |
| 65 | // BUILDFLAG(IS_ANDROID) |
| Benoit Lize | 448ee88 | 2017-08-31 13:32:12 | [diff] [blame] | 66 | |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 67 | // Convert a POSIX timeval to microseconds. |
| avi | beced7c | 2015-12-24 06:47:59 | [diff] [blame] | 68 | BASE_EXPORT int64_t TimeValToMicroseconds(const struct timeval& tv); |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 69 | |
| Etienne Pierre-doray | 490c80f | 2024-12-05 00:30:14 | [diff] [blame] | 70 | enum class ProcessUsageError { |
| Joe Mason | 550eed6 | 2024-03-25 18:07:31 | [diff] [blame] | 71 | // The OS returned an error while measuring the CPU usage. The possible causes |
| 72 | // vary by platform. |
| 73 | kSystemError, |
| 74 | |
| 75 | // Process CPU usage couldn't be measured because the process wasn't running. |
| 76 | // Some platforms may return kSystemError instead in this situation. |
| 77 | kProcessNotFound, |
| Joe Mason | 550eed6 | 2024-03-25 18:07:31 | [diff] [blame] | 78 | }; |
| 79 | |
| Etienne Pierre-doray | 490c80f | 2024-12-05 00:30:14 | [diff] [blame] | 80 | using ProcessCPUUsageError = ProcessUsageError; |
| 81 | |
| 82 | struct ProcessMemoryInfo { |
| 83 | uint64_t resident_set_bytes = 0; |
| 84 | |
| 85 | #if BUILDFLAG(IS_APPLE) |
| 86 | uint64_t physical_footprint_bytes = 0; |
| 87 | uint64_t internal_bytes = 0; |
| 88 | uint64_t compressed_bytes = 0; |
| 89 | #endif // BUILDFLAG(IS_APPLE) |
| 90 | |
| 91 | #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ |
| 92 | BUILDFLAG(IS_FUCHSIA) |
| 93 | uint64_t rss_anon_bytes = 0; |
| 94 | uint64_t vm_swap_bytes = 0; |
| 95 | #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || |
| 96 | // BUILDFLAG(IS_ANDROID) |
| 97 | |
| 98 | #if BUILDFLAG(IS_WIN) |
| 99 | uint64_t private_bytes = 0; |
| 100 | #endif // BUILDFLAG(IS_WIN) |
| 101 | |
| 102 | // On iOS, |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 103 | // TBD: https://crbug.com/41315025 |
| Etienne Pierre-doray | 490c80f | 2024-12-05 00:30:14 | [diff] [blame] | 104 | }; |
| 105 | |
| erikchen | 52b7b6b | 2018-03-23 21:58:50 | [diff] [blame] | 106 | // Provides performance metrics for a specified process (CPU usage and IO |
| 107 | // counters). Use CreateCurrentProcessMetrics() to get an instance for the |
| fdoray | 28787424 | 2015-11-12 01:12:32 | [diff] [blame] | 108 | // current process, or CreateProcessMetrics() to get an instance for an |
| 109 | // arbitrary process. Then, access the information with the different get |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 110 | // methods. |
| erikchen | 52b7b6b | 2018-03-23 21:58:50 | [diff] [blame] | 111 | // |
| 112 | // This class exposes a few platform-specific APIs for parsing memory usage, but |
| 113 | // these are not intended to generalize to other platforms, since the memory |
| 114 | // models differ substantially. |
| 115 | // |
| 116 | // To obtain consistent memory metrics, use the memory_instrumentation service. |
| 117 | // |
| 118 | // For further documentation on memory, see |
| Olivier Li | eb72ef0 | 2021-05-11 19:52:27 | [diff] [blame] | 119 | // https://chromium.googlesource.com/chromium/src/+/HEAD/docs/README.md#Memory |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 120 | class BASE_EXPORT ProcessMetrics { |
| 121 | public: |
| Peter Boström | 7319bbd | 2021-09-15 22:59:38 | [diff] [blame] | 122 | ProcessMetrics(const ProcessMetrics&) = delete; |
| 123 | ProcessMetrics& operator=(const ProcessMetrics&) = delete; |
| 124 | |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 125 | ~ProcessMetrics(); |
| 126 | |
| 127 | // Creates a ProcessMetrics for the specified process. |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 128 | #if !BUILDFLAG(IS_MAC) |
| thestig | 0df2bae8 | 2016-07-26 17:59:36 | [diff] [blame] | 129 | static std::unique_ptr<ProcessMetrics> CreateProcessMetrics( |
| 130 | ProcessHandle process); |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 131 | #else |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 132 | |
| 133 | // The port provider needs to outlive the ProcessMetrics object returned by |
| 134 | // this function. If NULL is passed as provider, the returned object |
| 135 | // only returns valid metrics if |process| is the current process. |
| thestig | 0df2bae8 | 2016-07-26 17:59:36 | [diff] [blame] | 136 | static std::unique_ptr<ProcessMetrics> CreateProcessMetrics( |
| 137 | ProcessHandle process, |
| 138 | PortProvider* port_provider); |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 139 | #endif // !BUILDFLAG(IS_MAC) |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 140 | |
| fdoray | 28787424 | 2015-11-12 01:12:32 | [diff] [blame] | 141 | // Creates a ProcessMetrics for the current process. This a cross-platform |
| 142 | // convenience wrapper for CreateProcessMetrics(). |
| thestig | 0df2bae8 | 2016-07-26 17:59:36 | [diff] [blame] | 143 | static std::unique_ptr<ProcessMetrics> CreateCurrentProcessMetrics(); |
| fdoray | 28787424 | 2015-11-12 01:12:32 | [diff] [blame] | 144 | |
| Etienne Pierre-doray | 490c80f | 2024-12-05 00:30:14 | [diff] [blame] | 145 | // Provides synchronous access to memory metrics for a process. This interface |
| 146 | // has platform-specific restrictions: |
| 147 | // * On Android, due to sandboxing restrictions, processes can only access |
| 148 | // memory metrics for themselves. |
| 149 | // * On Linux, due to sandboxing restrictions, only the privileged browser |
| 150 | // process has access to memory metrics for sandboxed child processes. |
| 151 | // * On Fuchsia, due to the API expecting a ProcessId rather than a |
| 152 | // ProcessHandle, processes can only access memory metrics for themselves |
| 153 | // or for children of base::GetDefaultJob(). |
| 154 | base::expected<ProcessMemoryInfo, ProcessUsageError> GetMemoryInfo() const; |
| erikchen | d447bb6 | 2018-03-08 22:06:24 | [diff] [blame] | 155 | |
| Wez | 4ae8f29 | 2017-09-11 20:52:03 | [diff] [blame] | 156 | // Returns the percentage of time spent executing, across all threads of the |
| Patrick Monette | 87b033b6 | 2022-08-24 20:06:12 | [diff] [blame] | 157 | // process, in the interval since the last time the method was called, using |
| 158 | // the current |cumulative_cpu|. Since this considers the total execution time |
| 159 | // across all threads in a process, the result can easily exceed 100% in |
| 160 | // multi-thread processes running on multi-core systems. In general the result |
| 161 | // is therefore a value in the range 0% to |
| 162 | // SysInfo::NumberOfProcessors() * 100%. |
| Wez | 4ae8f29 | 2017-09-11 20:52:03 | [diff] [blame] | 163 | // |
| 164 | // To obtain the percentage of total available CPU resources consumed by this |
| 165 | // process over the interval, the caller must divide by NumberOfProcessors(). |
| 166 | // |
| 167 | // Since this API measures usage over an interval, it will return zero on the |
| 168 | // first call, and an actual value only on the second and subsequent calls. |
| Patrick Monette | 87b033b6 | 2022-08-24 20:06:12 | [diff] [blame] | 169 | [[nodiscard]] double GetPlatformIndependentCPUUsage(TimeDelta cumulative_cpu); |
| 170 | |
| 171 | // Same as the above, but automatically calls GetCumulativeCPUUsage() to |
| Joe Mason | ba14528 | 2024-03-12 20:18:19 | [diff] [blame] | 172 | // determine the current cumulative CPU. Returns nullopt if |
| 173 | // GetCumulativeCPUUsage() fails. |
| Joe Mason | 307893c | 2024-04-03 18:39:38 | [diff] [blame] | 174 | base::expected<double, ProcessCPUUsageError> GetPlatformIndependentCPUUsage(); |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 175 | |
| Sigurdur Asgeirsson | eb27eae7 | 2018-05-16 15:29:10 | [diff] [blame] | 176 | // Returns the cumulative CPU usage across all threads of the process since |
| Joe Mason | ba14528 | 2024-03-12 20:18:19 | [diff] [blame] | 177 | // process start, or nullopt on error. In case of multi-core processors, a |
| 178 | // process can consume CPU at a rate higher than wall-clock time, e.g. two |
| 179 | // cores at full utilization will result in a time delta of 2 seconds/per 1 |
| 180 | // wall-clock second. |
| Joe Mason | 307893c | 2024-04-03 18:39:38 | [diff] [blame] | 181 | base::expected<TimeDelta, ProcessCPUUsageError> GetCumulativeCPUUsage(); |
| Sigurdur Asgeirsson | eb27eae7 | 2018-05-16 15:29:10 | [diff] [blame] | 182 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 183 | #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ |
| 184 | BUILDFLAG(IS_AIX) |
| Eric Seckler | 9db21395 | 2020-06-12 08:48:19 | [diff] [blame] | 185 | // Emits the cumulative CPU usage for all currently active threads since they |
| 186 | // were started into the output parameter (replacing its current contents). |
| 187 | // Threads that have already terminated will not be reported. Thus, the sum of |
| 188 | // these times may not equal the value returned by GetCumulativeCPUUsage(). |
| 189 | // Returns false on failure. We return the usage via an output parameter to |
| 190 | // allow reuse of CPUUsagePerThread's std::vector by the caller, e.g. to avoid |
| Eric Seckler | dbc29da | 2020-07-10 11:54:05 | [diff] [blame] | 191 | // allocations between repeated calls to this method. |
| Eric Seckler | 9db21395 | 2020-06-12 08:48:19 | [diff] [blame] | 192 | // NOTE: Currently only supported on Linux/Android. |
| 193 | using CPUUsagePerThread = std::vector<std::pair<PlatformThreadId, TimeDelta>>; |
| 194 | bool GetCumulativeCPUUsagePerThread(CPUUsagePerThread&); |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 195 | #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || |
| 196 | // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX) |
| Eric Seckler | dbc29da | 2020-07-10 11:54:05 | [diff] [blame] | 197 | |
| [email protected] | ac6d065 | 2014-01-14 00:06:37 | [diff] [blame] | 198 | // Returns the number of average idle cpu wakeups per second since the last |
| 199 | // call. |
| 200 | int GetIdleWakeupsPerSecond(); |
| 201 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 202 | #if BUILDFLAG(IS_APPLE) |
| Leonard Grey | d1fc0b4 | 2017-10-09 17:01:01 | [diff] [blame] | 203 | // Returns the number of average "package idle exits" per second, which have |
| 204 | // a higher energy impact than a regular wakeup, since the last call. |
| 205 | // |
| 206 | // From the powermetrics man page: |
| 207 | // "With the exception of some Mac Pro systems, Mac and |
| 208 | // iOS systems are typically single package systems, wherein all CPUs are |
| 209 | // part of a single processor complex (typically a single IC die) with shared |
| 210 | // logic that can include (depending on system specifics) shared last level |
| 211 | // caches, an integrated memory controller etc. When all CPUs in the package |
| 212 | // are idle, the hardware can power-gate significant portions of the shared |
| 213 | // logic in addition to each individual processor's logic, as well as take |
| 214 | // measures such as placing DRAM in to self-refresh (also referred to as |
| 215 | // auto-refresh), place interconnects into lower-power states etc" |
| 216 | int GetPackageIdleWakeupsPerSecond(); |
| 217 | #endif |
| 218 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 219 | #if BUILDFLAG(IS_POSIX) |
| afakhry | 43b3bb77 | 2015-12-15 21:57:59 | [diff] [blame] | 220 | // Returns the number of file descriptors currently open by the process, or |
| 221 | // -1 on error. |
| 222 | int GetOpenFdCount() const; |
| dcastagna | f454af4e | 2017-03-15 23:34:14 | [diff] [blame] | 223 | |
| 224 | // Returns the soft limit of file descriptors that can be opened by the |
| 225 | // process, or -1 on error. |
| 226 | int GetOpenFdSoftLimit() const; |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 227 | #endif // BUILDFLAG(IS_POSIX) |
| afakhry | 43b3bb77 | 2015-12-15 21:57:59 | [diff] [blame] | 228 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 229 | #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) |
| Benoit Lize | 448ee88 | 2017-08-31 13:32:12 | [diff] [blame] | 230 | // Minor and major page fault count as reported by /proc/[pid]/stat. |
| 231 | // Returns true for success. |
| 232 | bool GetPageFaultCounts(PageFaultCounts* counts) const; |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 233 | #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || |
| 234 | // BUILDFLAG(IS_ANDROID) |
| hjd | bae6b3b | 2017-05-17 04:18:05 | [diff] [blame] | 235 | |
| keishi | 12b598b9 | 2017-06-20 10:25:26 | [diff] [blame] | 236 | // Returns total memory usage of malloc. |
| 237 | size_t GetMallocUsage(); |
| 238 | |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 239 | private: |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 240 | #if !BUILDFLAG(IS_MAC) |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 241 | explicit ProcessMetrics(ProcessHandle process); |
| 242 | #else |
| 243 | ProcessMetrics(ProcessHandle process, PortProvider* port_provider); |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 244 | #endif // !BUILDFLAG(IS_MAC) |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 245 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 246 | #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ |
| 247 | BUILDFLAG(IS_AIX) |
| avi | beced7c | 2015-12-24 06:47:59 | [diff] [blame] | 248 | int CalculateIdleWakeupsPerSecond(uint64_t absolute_idle_wakeups); |
| thestig | 75844fdb | 2014-09-09 19:47:10 | [diff] [blame] | 249 | #endif |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 250 | #if BUILDFLAG(IS_APPLE) |
| Leonard Grey | d1fc0b4 | 2017-10-09 17:01:01 | [diff] [blame] | 251 | // The subset of wakeups that cause a "package exit" can be tracked on macOS. |
| 252 | // See |GetPackageIdleWakeupsForSecond| comment for more info. |
| 253 | int CalculatePackageIdleWakeupsPerSecond( |
| 254 | uint64_t absolute_package_idle_wakeups); |
| Gyuyoung Kim | 7229950b | 2023-07-21 00:20:43 | [diff] [blame] | 255 | |
| 256 | // Queries the port provider if it's set. |
| Francois Doray | 789889031 | 2024-02-05 18:24:26 | [diff] [blame] | 257 | mach_port_t TaskForHandle(ProcessHandle process_handle) const; |
| Leonard Grey | d1fc0b4 | 2017-10-09 17:01:01 | [diff] [blame] | 258 | #endif |
| thestig | 75844fdb | 2014-09-09 19:47:10 | [diff] [blame] | 259 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 260 | #if BUILDFLAG(IS_WIN) |
| stanisc | e73f1a4 | 2017-03-31 21:42:22 | [diff] [blame] | 261 | win::ScopedHandle process_; |
| 262 | #else |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 263 | ProcessHandle process_; |
| stanisc | e73f1a4 | 2017-03-31 21:42:22 | [diff] [blame] | 264 | #endif |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 265 | |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 266 | // Used to store the previous times and CPU usage counts so we can |
| 267 | // compute the CPU usage between calls. |
| [email protected] | e21c332 | 2014-04-06 21:25:01 | [diff] [blame] | 268 | TimeTicks last_cpu_time_; |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 269 | #if !BUILDFLAG(IS_FREEBSD) || !BUILDFLAG(IS_POSIX) |
| Sigurdur Asgeirsson | eb27eae7 | 2018-05-16 15:29:10 | [diff] [blame] | 270 | TimeDelta last_cumulative_cpu_; |
| Mostyn Bramley-Moore | aae9672 | 2018-03-24 13:38:48 | [diff] [blame] | 271 | #endif |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 272 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 273 | #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ |
| 274 | BUILDFLAG(IS_AIX) |
| [email protected] | ac6d065 | 2014-01-14 00:06:37 | [diff] [blame] | 275 | // Same thing for idle wakeups. |
| [email protected] | e21c332 | 2014-04-06 21:25:01 | [diff] [blame] | 276 | TimeTicks last_idle_wakeups_time_; |
| avi | beced7c | 2015-12-24 06:47:59 | [diff] [blame] | 277 | uint64_t last_absolute_idle_wakeups_; |
| thestig | a0d051ed | 2014-09-08 21:41:17 | [diff] [blame] | 278 | #endif |
| [email protected] | ac6d065 | 2014-01-14 00:06:37 | [diff] [blame] | 279 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 280 | #if BUILDFLAG(IS_APPLE) |
| Leonard Grey | d1fc0b4 | 2017-10-09 17:01:01 | [diff] [blame] | 281 | // And same thing for package idle exit wakeups. |
| 282 | TimeTicks last_package_idle_wakeups_time_; |
| 283 | uint64_t last_absolute_package_idle_wakeups_; |
| Joe Mason | f75bf18 | 2023-10-17 22:16:25 | [diff] [blame] | 284 | |
| 285 | // Works around a race condition when combining two task_info() calls to |
| 286 | // measure CPU time. |
| 287 | TimeDelta last_measured_cpu_; |
| Leonard Grey | d1fc0b4 | 2017-10-09 17:01:01 | [diff] [blame] | 288 | #endif |
| Gyuyoung Kim | 7229950b | 2023-07-21 00:20:43 | [diff] [blame] | 289 | |
| 290 | #if BUILDFLAG(IS_MAC) |
| 291 | raw_ptr<PortProvider> port_provider_; |
| 292 | #endif // BUILDFLAG(IS_MAC) |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 293 | }; |
| 294 | |
| 295 | // Returns the memory committed by the system in KBytes. |
| 296 | // Returns 0 if it can't compute the commit charge. |
| 297 | BASE_EXPORT size_t GetSystemCommitCharge(); |
| 298 | |
| [email protected] | 103ff351 | 2013-08-22 07:19:30 | [diff] [blame] | 299 | // Returns the maximum number of file descriptors that can be open by a process |
| 300 | // at once. If the number is unavailable, a conservative best guess is returned. |
| cmumford | bf82318 | 2014-11-20 16:32:56 | [diff] [blame] | 301 | BASE_EXPORT size_t GetMaxFds(); |
| [email protected] | b9f44b2 | 2014-05-29 23:15:55 | [diff] [blame] | 302 | |
| Matthew Cary | 144069d | 2019-07-11 19:26:17 | [diff] [blame] | 303 | // Returns the maximum number of handles that can be open at once per process. |
| 304 | BASE_EXPORT size_t GetHandleLimit(); |
| 305 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 306 | #if BUILDFLAG(IS_POSIX) |
| Bo Liu | 6f2ff42c | 2018-05-14 18:29:15 | [diff] [blame] | 307 | // Increases the file descriptor soft limit to |max_descriptors| or the OS hard |
| 308 | // limit, whichever is lower. If the limit is already higher than |
| 309 | // |max_descriptors|, then nothing happens. |
| 310 | BASE_EXPORT void IncreaseFdLimitTo(unsigned int max_descriptors); |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 311 | #endif // BUILDFLAG(IS_POSIX) |
| [email protected] | 103ff351 | 2013-08-22 07:19:30 | [diff] [blame] | 312 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 313 | #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || \ |
| 314 | BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX) || \ |
| 315 | BUILDFLAG(IS_FUCHSIA) |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 316 | // Data about system-wide memory consumption. Available on Windows, Mac, Linux, |
| 317 | // Android and Chrome OS. |
| 318 | // |
| 319 | // The values are kept in ByteCount but depending on the platform, the |
| 320 | // granularity might be at the KB level or higher. |
| georgesak | 7144e04 | 2015-07-29 17:11:42 | [diff] [blame] | 321 | // |
| mkolom | 01ac10b | 2017-03-22 01:47:29 | [diff] [blame] | 322 | // Total memory are available on all platforms that implement |
| georgesak | ae7209ae | 2015-08-10 20:40:09 | [diff] [blame] | 323 | // GetSystemMemoryInfo(). Total/free swap memory are available on all platforms |
| 324 | // except on Mac. Buffers/cached/active_anon/inactive_anon/active_file/ |
| mkolom | 01ac10b | 2017-03-22 01:47:29 | [diff] [blame] | 325 | // inactive_file/dirty/reclaimable/pswpin/pswpout/pgmajfault are available on |
| Kuo-Hsin Yang | 7cc65fc | 2020-10-12 14:02:27 | [diff] [blame] | 326 | // Linux/Android/Chrome OS. Shmem/slab are Chrome OS only. |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 327 | // Speculative/file_backed/purgeable are Mac and iOS only. Free is absent on |
| 328 | // Windows (see "avail_phys" below). |
| 329 | struct BASE_EXPORT SystemMemoryInfo { |
| 330 | SystemMemoryInfo(); |
| 331 | SystemMemoryInfo(const SystemMemoryInfo& other); |
| 332 | SystemMemoryInfo& operator=(const SystemMemoryInfo& other); |
| georgesak | 7144e04 | 2015-07-29 17:11:42 | [diff] [blame] | 333 | |
| Alex Attar | d42f011 | 2025-11-13 20:03:57 | [diff] [blame] | 334 | // TODO(crbug.com/458489438): Migrate all generic ByteCount usages in |
| 335 | // base/system and base/memory to the new types. |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 336 | ByteCount total; |
| georgesak | 7144e04 | 2015-07-29 17:11:42 | [diff] [blame] | 337 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 338 | #if !BUILDFLAG(IS_WIN) |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 339 | ByteCount free; |
| mkolom | 01ac10b | 2017-03-22 01:47:29 | [diff] [blame] | 340 | #endif |
| 341 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 342 | #if BUILDFLAG(IS_WIN) |
| mkolom | 01ac10b | 2017-03-22 01:47:29 | [diff] [blame] | 343 | // "This is the amount of physical memory that can be immediately reused |
| 344 | // without having to write its contents to disk first. It is the sum of the |
| 345 | // size of the standby, free, and zero lists." (MSDN). |
| 346 | // Standby: not modified pages of physical ram (file-backed memory) that are |
| 347 | // not actively being used. |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 348 | ByteCount avail_phys; |
| mkolom | 01ac10b | 2017-03-22 01:47:29 | [diff] [blame] | 349 | #endif |
| 350 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 351 | #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ |
| 352 | BUILDFLAG(IS_AIX) |
| halliwell | c2eb0f97 | 2016-06-17 19:04:52 | [diff] [blame] | 353 | // This provides an estimate of available memory as described here: |
| 354 | // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773 |
| 355 | // NOTE: this is ONLY valid in kernels 3.14 and up. Its value will always |
| 356 | // be 0 in earlier kernel versions. |
| mkolom | 01ac10b | 2017-03-22 01:47:29 | [diff] [blame] | 357 | // Note: it includes _all_ file-backed memory (active + inactive). |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 358 | ByteCount available; |
| halliwell | c2eb0f97 | 2016-06-17 19:04:52 | [diff] [blame] | 359 | #endif |
| 360 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 361 | #if !BUILDFLAG(IS_APPLE) |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 362 | ByteCount swap_total; |
| 363 | ByteCount swap_free; |
| georgesak | 7144e04 | 2015-07-29 17:11:42 | [diff] [blame] | 364 | #endif |
| 365 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 366 | #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ |
| 367 | BUILDFLAG(IS_AIX) || BUILDFLAG(IS_FUCHSIA) |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 368 | ByteCount buffers; |
| 369 | ByteCount cached; |
| 370 | ByteCount active_anon; |
| 371 | ByteCount inactive_anon; |
| 372 | ByteCount active_file; |
| 373 | ByteCount inactive_file; |
| 374 | ByteCount dirty; |
| 375 | ByteCount reclaimable; |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 376 | #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || |
| 377 | // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_AIX) BUILDFLAG(IS_FUCHSIA) |
| georgesak | 7144e04 | 2015-07-29 17:11:42 | [diff] [blame] | 378 | |
| Eric Willigers | 611cf54e | 2022-04-28 02:22:14 | [diff] [blame] | 379 | #if BUILDFLAG(IS_CHROMEOS) |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 380 | ByteCount shmem; |
| 381 | ByteCount slab; |
| Eric Willigers | 611cf54e | 2022-04-28 02:22:14 | [diff] [blame] | 382 | #endif // BUILDFLAG(IS_CHROMEOS) |
| mkolom | 01ac10b | 2017-03-22 01:47:29 | [diff] [blame] | 383 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 384 | #if BUILDFLAG(IS_APPLE) |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 385 | ByteCount speculative; |
| 386 | ByteCount file_backed; |
| 387 | ByteCount purgeable; |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 388 | #endif // BUILDFLAG(IS_APPLE) |
| Alex Attar | d42f011 | 2025-11-13 20:03:57 | [diff] [blame] | 389 | |
| 390 | // Returns a cross-platform estimation of available physical memory. |
| 391 | // This value is an approximation of the amount of physical memory that |
| 392 | // can be used without the system needing to swap. |
| 393 | ByteCount GetAvailablePhysicalMemory() const; |
| georgesak | 7144e04 | 2015-07-29 17:11:42 | [diff] [blame] | 394 | }; |
| 395 | |
| 396 | // On Linux/Android/Chrome OS, system-wide memory consumption data is parsed |
| 397 | // from /proc/meminfo and /proc/vmstat. On Windows/Mac, it is obtained using |
| 398 | // system API calls. |
| 399 | // |
| 400 | // Fills in the provided |meminfo| structure. Returns true on success. |
| 401 | // Exposed for memory debugging widget. |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 402 | BASE_EXPORT bool GetSystemMemoryInfo(SystemMemoryInfo* meminfo); |
| georgesak | 7144e04 | 2015-07-29 17:11:42 | [diff] [blame] | 403 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 404 | #endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || |
| 405 | // BUILDFLAG(IS_CHROMEOS) BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX) || |
| 406 | // BUILDFLAG(IS_FUCHSIA) |
| georgesak | 7144e04 | 2015-07-29 17:11:42 | [diff] [blame] | 407 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 408 | #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \ |
| 409 | BUILDFLAG(IS_AIX) |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 410 | // Parse the data found in /proc/<pid>/stat and return the sum of the |
| 411 | // CPU-related ticks. Returns -1 on parse error. |
| 412 | // Exposed for testing. |
| Helmut Januschka | bfa62f7 | 2024-04-04 15:18:31 | [diff] [blame] | 413 | BASE_EXPORT int ParseProcStatCPU(std::string_view input); |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 414 | |
| [email protected] | 103ff351 | 2013-08-22 07:19:30 | [diff] [blame] | 415 | // Get the number of threads of |process| as available in /proc/<pid>/stat. |
| 416 | // This should be used with care as no synchronization with running threads is |
| 417 | // done. This is mostly useful to guarantee being single-threaded. |
| 418 | // Returns 0 on failure. |
| Peter Kasting | 25acd594 | 2022-07-07 17:45:15 | [diff] [blame] | 419 | BASE_EXPORT int64_t GetNumberOfThreads(ProcessHandle process); |
| [email protected] | 103ff351 | 2013-08-22 07:19:30 | [diff] [blame] | 420 | |
| 421 | // /proc/self/exe refers to the current executable. |
| 422 | BASE_EXPORT extern const char kProcSelfExe[]; |
| 423 | |
| [email protected] | 70baebc | 2013-11-02 16:58:44 | [diff] [blame] | 424 | // Parses a string containing the contents of /proc/meminfo |
| 425 | // returns true on success or false for a parsing error |
| thestig | bc11dd6 | 2017-05-04 18:55:08 | [diff] [blame] | 426 | // Exposed for testing. |
| Helmut Januschka | bfa62f7 | 2024-04-04 15:18:31 | [diff] [blame] | 427 | BASE_EXPORT bool ParseProcMeminfo(std::string_view input, |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 428 | SystemMemoryInfo* meminfo); |
| [email protected] | 70baebc | 2013-11-02 16:58:44 | [diff] [blame] | 429 | |
| Joe Mason | 87c33f1 | 2024-02-09 15:47:04 | [diff] [blame] | 430 | // Returns the memory committed by the system in KBytes, as from |
| 431 | // GetSystemCommitCharge(), using data from `meminfo` instead of /proc/meminfo. |
| 432 | // Exposed for testing. |
| 433 | BASE_EXPORT size_t |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 434 | GetSystemCommitChargeFromMeminfo(const SystemMemoryInfo& meminfo); |
| Joe Mason | 87c33f1 | 2024-02-09 15:47:04 | [diff] [blame] | 435 | |
| Kenichi Ishibashi | 4487152 | 2017-10-23 07:12:19 | [diff] [blame] | 436 | // Data from /proc/vmstat. |
| 437 | struct BASE_EXPORT VmStatInfo { |
| Peter Kasting | 6a4bf14c | 2022-07-13 14:53:33 | [diff] [blame] | 438 | uint64_t pswpin = 0; |
| 439 | uint64_t pswpout = 0; |
| 440 | uint64_t pgmajfault = 0; |
| 441 | uint64_t oom_kill = 0; |
| Kenichi Ishibashi | 4487152 | 2017-10-23 07:12:19 | [diff] [blame] | 442 | }; |
| 443 | |
| 444 | // Retrieves data from /proc/vmstat about system-wide vm operations. |
| 445 | // Fills in the provided |vmstat| structure. Returns true on success. |
| 446 | BASE_EXPORT bool GetVmStatInfo(VmStatInfo* vmstat); |
| 447 | |
| [email protected] | 70baebc | 2013-11-02 16:58:44 | [diff] [blame] | 448 | // Parses a string containing the contents of /proc/vmstat |
| 449 | // returns true on success or false for a parsing error |
| thestig | bc11dd6 | 2017-05-04 18:55:08 | [diff] [blame] | 450 | // Exposed for testing. |
| Helmut Januschka | bfa62f7 | 2024-04-04 15:18:31 | [diff] [blame] | 451 | BASE_EXPORT bool ParseProcVmstat(std::string_view input, VmStatInfo* vmstat); |
| [email protected] | 70baebc | 2013-11-02 16:58:44 | [diff] [blame] | 452 | |
| [email protected] | 669a0933 | 2013-08-30 22:59:14 | [diff] [blame] | 453 | // Data from /proc/diskstats about system-wide disk I/O. |
| 454 | struct BASE_EXPORT SystemDiskInfo { |
| 455 | SystemDiskInfo(); |
| Peter Kasting | e08ca1334 | 2021-07-08 02:46:57 | [diff] [blame] | 456 | SystemDiskInfo(const SystemDiskInfo&); |
| 457 | SystemDiskInfo& operator=(const SystemDiskInfo&); |
| [email protected] | 669a0933 | 2013-08-30 22:59:14 | [diff] [blame] | 458 | |
| Kenichi Ishibashi | 4487152 | 2017-10-23 07:12:19 | [diff] [blame] | 459 | uint64_t reads = 0; |
| 460 | uint64_t reads_merged = 0; |
| 461 | uint64_t sectors_read = 0; |
| 462 | uint64_t read_time = 0; |
| 463 | uint64_t writes = 0; |
| 464 | uint64_t writes_merged = 0; |
| 465 | uint64_t sectors_written = 0; |
| 466 | uint64_t write_time = 0; |
| 467 | uint64_t io = 0; |
| 468 | uint64_t io_time = 0; |
| 469 | uint64_t weighted_io_time = 0; |
| [email protected] | 669a0933 | 2013-08-30 22:59:14 | [diff] [blame] | 470 | }; |
| 471 | |
| thestig | a0d051ed | 2014-09-08 21:41:17 | [diff] [blame] | 472 | // Checks whether the candidate string is a valid disk name, [hsv]d[a-z]+ |
| [email protected] | 669a0933 | 2013-08-30 22:59:14 | [diff] [blame] | 473 | // for a generic disk or mmcblk[0-9]+ for the MMC case. |
| 474 | // Names of disk partitions (e.g. sda1) are not valid. |
| Helmut Januschka | bfa62f7 | 2024-04-04 15:18:31 | [diff] [blame] | 475 | BASE_EXPORT bool IsValidDiskName(std::string_view candidate); |
| [email protected] | 669a0933 | 2013-08-30 22:59:14 | [diff] [blame] | 476 | |
| 477 | // Retrieves data from /proc/diskstats about system-wide disk I/O. |
| 478 | // Fills in the provided |diskinfo| structure. Returns true on success. |
| 479 | BASE_EXPORT bool GetSystemDiskInfo(SystemDiskInfo* diskinfo); |
| thomasanderson | fc4688ab | 2016-09-10 01:19:43 | [diff] [blame] | 480 | |
| 481 | // Returns the amount of time spent in user space since boot across all CPUs. |
| 482 | BASE_EXPORT TimeDelta GetUserCpuTimeSinceBoot(); |
| Kenichi Ishibashi | 4487152 | 2017-10-23 07:12:19 | [diff] [blame] | 483 | |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 484 | #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || |
| 485 | // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX) |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 486 | |
| Eric Willigers | 611cf54e | 2022-04-28 02:22:14 | [diff] [blame] | 487 | #if BUILDFLAG(IS_CHROMEOS) |
| [email protected] | f413478 | 2013-08-29 21:25:20 | [diff] [blame] | 488 | // Data from files in directory /sys/block/zram0 about ZRAM usage. |
| 489 | struct BASE_EXPORT SwapInfo { |
| 490 | SwapInfo() |
| 491 | : num_reads(0), |
| 492 | num_writes(0), |
| 493 | compr_data_size(0), |
| 494 | orig_data_size(0), |
| Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 495 | mem_used_total(0) {} |
| [email protected] | f413478 | 2013-08-29 21:25:20 | [diff] [blame] | 496 | |
| Kenichi Ishibashi | 4487152 | 2017-10-23 07:12:19 | [diff] [blame] | 497 | uint64_t num_reads = 0; |
| 498 | uint64_t num_writes = 0; |
| 499 | uint64_t compr_data_size = 0; |
| 500 | uint64_t orig_data_size = 0; |
| 501 | uint64_t mem_used_total = 0; |
| [email protected] | f413478 | 2013-08-29 21:25:20 | [diff] [blame] | 502 | }; |
| 503 | |
| Chung-Sheng Wu | 838f843b | 2017-07-21 04:17:58 | [diff] [blame] | 504 | // Parses a string containing the contents of /sys/block/zram0/mm_stat. |
| 505 | // This should be used for the new ZRAM sysfs interfaces. |
| 506 | // Returns true on success or false for a parsing error. |
| 507 | // Exposed for testing. |
| Helmut Januschka | bfa62f7 | 2024-04-04 15:18:31 | [diff] [blame] | 508 | BASE_EXPORT bool ParseZramMmStat(std::string_view mm_stat_data, |
| 509 | SwapInfo* swap_info); |
| Chung-Sheng Wu | 838f843b | 2017-07-21 04:17:58 | [diff] [blame] | 510 | |
| 511 | // Parses a string containing the contents of /sys/block/zram0/stat |
| 512 | // This should be used for the new ZRAM sysfs interfaces. |
| 513 | // Returns true on success or false for a parsing error. |
| 514 | // Exposed for testing. |
| Helmut Januschka | bfa62f7 | 2024-04-04 15:18:31 | [diff] [blame] | 515 | BASE_EXPORT bool ParseZramStat(std::string_view stat_data, SwapInfo* swap_info); |
| Chung-Sheng Wu | 838f843b | 2017-07-21 04:17:58 | [diff] [blame] | 516 | |
| [email protected] | f413478 | 2013-08-29 21:25:20 | [diff] [blame] | 517 | // In ChromeOS, reads files from /sys/block/zram0 that contain ZRAM usage data. |
| 518 | // Fills in the provided |swap_data| structure. |
| Chung-Sheng Wu | 838f843b | 2017-07-21 04:17:58 | [diff] [blame] | 519 | // Returns true on success or false for a parsing error. |
| 520 | BASE_EXPORT bool GetSwapInfo(SwapInfo* swap_info); |
| Kuo-Hsin Yang | 7cc65fc | 2020-10-12 14:02:27 | [diff] [blame] | 521 | |
| 522 | // Data about GPU memory usage. These fields will be -1 if not supported. |
| 523 | struct BASE_EXPORT GraphicsMemoryInfoKB { |
| Kuo-Hsin Yang | 7cc65fc | 2020-10-12 14:02:27 | [diff] [blame] | 524 | int gpu_objects = -1; |
| 525 | int64_t gpu_memory_size = -1; |
| 526 | }; |
| 527 | |
| 528 | // Report on Chrome OS graphics memory. Returns true on success. |
| 529 | // /run/debugfs_gpu is a bind mount into /sys/kernel/debug and synchronously |
| 530 | // reading the in-memory files in /sys is fast in most cases. On platform that |
| 531 | // reading the graphics memory info is slow, this function returns false. |
| 532 | BASE_EXPORT bool GetGraphicsMemoryInfo(GraphicsMemoryInfoKB* gpu_meminfo); |
| 533 | |
| Eric Willigers | 611cf54e | 2022-04-28 02:22:14 | [diff] [blame] | 534 | #endif // BUILDFLAG(IS_CHROMEOS) |
| [email protected] | f413478 | 2013-08-29 21:25:20 | [diff] [blame] | 535 | |
| Etienne Bergeron | 0b9d2b6 | 2018-08-15 20:34:10 | [diff] [blame] | 536 | struct BASE_EXPORT SystemPerformanceInfo { |
| 537 | SystemPerformanceInfo(); |
| 538 | SystemPerformanceInfo(const SystemPerformanceInfo& other); |
| Arthur Eubanks | 08f7b054 | 2022-09-16 00:53:01 | [diff] [blame] | 539 | SystemPerformanceInfo& operator=(const SystemPerformanceInfo& other); |
| Etienne Bergeron | 0b9d2b6 | 2018-08-15 20:34:10 | [diff] [blame] | 540 | |
| Etienne Bergeron | 0b9d2b6 | 2018-08-15 20:34:10 | [diff] [blame] | 541 | // Total idle time of all processes in the system (units of 100 ns). |
| 542 | uint64_t idle_time = 0; |
| 543 | // Number of bytes read. |
| 544 | uint64_t read_transfer_count = 0; |
| 545 | // Number of bytes written. |
| 546 | uint64_t write_transfer_count = 0; |
| 547 | // Number of bytes transferred (e.g. DeviceIoControlFile) |
| 548 | uint64_t other_transfer_count = 0; |
| 549 | // The amount of read operations. |
| 550 | uint64_t read_operation_count = 0; |
| 551 | // The amount of write operations. |
| 552 | uint64_t write_operation_count = 0; |
| 553 | // The amount of other operations. |
| 554 | uint64_t other_operation_count = 0; |
| 555 | // The number of pages written to the system's pagefiles. |
| 556 | uint64_t pagefile_pages_written = 0; |
| 557 | // The number of write operations performed on the system's pagefiles. |
| 558 | uint64_t pagefile_pages_write_ios = 0; |
| Sebastien Marchand | 57c036da | 2018-10-04 20:53:20 | [diff] [blame] | 559 | // The number of pages of physical memory available to processes running on |
| 560 | // the system. |
| 561 | uint64_t available_pages = 0; |
| 562 | // The number of pages read from disk to resolve page faults. |
| 563 | uint64_t pages_read = 0; |
| 564 | // The number of read operations initiated to resolve page faults. |
| 565 | uint64_t page_read_ios = 0; |
| Etienne Bergeron | 0b9d2b6 | 2018-08-15 20:34:10 | [diff] [blame] | 566 | }; |
| 567 | |
| 568 | // Retrieves performance counters from the operating system. |
| 569 | // Fills in the provided |info| structure. Returns true on success. |
| 570 | BASE_EXPORT bool GetSystemPerformanceInfo(SystemPerformanceInfo* info); |
| 571 | |
| [email protected] | 14b4f10 | 2013-08-22 01:12:19 | [diff] [blame] | 572 | // Collects and holds performance metrics for system memory and disk. |
| 573 | // Provides functionality to retrieve the data on various platforms and |
| 574 | // to serialize the stored data. |
| Sebastien Marchand | dbe43bab | 2019-02-06 18:25:51 | [diff] [blame] | 575 | class BASE_EXPORT SystemMetrics { |
| [email protected] | 14b4f10 | 2013-08-22 01:12:19 | [diff] [blame] | 576 | public: |
| [email protected] | 49b0cf8 | 2013-09-03 23:46:54 | [diff] [blame] | 577 | SystemMetrics(); |
| [email protected] | 14b4f10 | 2013-08-22 01:12:19 | [diff] [blame] | 578 | |
| 579 | static SystemMetrics Sample(); |
| 580 | |
| [email protected] | 14b4f10 | 2013-08-22 01:12:19 | [diff] [blame] | 581 | private: |
| [email protected] | 669a0933 | 2013-08-30 22:59:14 | [diff] [blame] | 582 | FRIEND_TEST_ALL_PREFIXES(SystemMetricsTest, SystemMetrics); |
| 583 | |
| [email protected] | 14b4f10 | 2013-08-22 01:12:19 | [diff] [blame] | 584 | size_t committed_memory_; |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 585 | #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) |
| Avi Drissman | c4404ffc | 2025-08-05 21:48:06 | [diff] [blame] | 586 | SystemMemoryInfo memory_info_; |
| Kenichi Ishibashi | 4487152 | 2017-10-23 07:12:19 | [diff] [blame] | 587 | VmStatInfo vmstat_info_; |
| [email protected] | 49b0cf8 | 2013-09-03 23:46:54 | [diff] [blame] | 588 | SystemDiskInfo disk_info_; |
| 589 | #endif |
| Eric Willigers | 611cf54e | 2022-04-28 02:22:14 | [diff] [blame] | 590 | #if BUILDFLAG(IS_CHROMEOS) |
| [email protected] | 49b0cf8 | 2013-09-03 23:46:54 | [diff] [blame] | 591 | SwapInfo swap_info_; |
| Kuo-Hsin Yang | 7cc65fc | 2020-10-12 14:02:27 | [diff] [blame] | 592 | GraphicsMemoryInfoKB gpu_memory_info_; |
| [email protected] | 14b4f10 | 2013-08-22 01:12:19 | [diff] [blame] | 593 | #endif |
| Xiaohan Wang | 37e8161 | 2022-01-15 18:27:00 | [diff] [blame] | 594 | #if BUILDFLAG(IS_WIN) |
| Etienne Bergeron | 0b9d2b6 | 2018-08-15 20:34:10 | [diff] [blame] | 595 | SystemPerformanceInfo performance_; |
| 596 | #endif |
| [email protected] | 14b4f10 | 2013-08-22 01:12:19 | [diff] [blame] | 597 | }; |
| 598 | |
| Gyuyoung Kim | 52e933789 | 2023-04-20 15:08:41 | [diff] [blame] | 599 | #if BUILDFLAG(IS_APPLE) |
| erikchen | 12531f2 | 2017-04-21 19:48:51 | [diff] [blame] | 600 | enum class MachVMRegionResult { |
| 601 | // There were no more memory regions between |address| and the end of the |
| 602 | // virtual address space. |
| 603 | Finished, |
| 604 | |
| 605 | // All output parameters are invalid. |
| 606 | Error, |
| 607 | |
| 608 | // All output parameters are filled in. |
| 609 | Success |
| 610 | }; |
| 611 | |
| 612 | // Returns info on the first memory region at or after |address|, including |
| erikchen | 12531f2 | 2017-04-21 19:48:51 | [diff] [blame] | 613 | // protection values. On Success, |size| reflects the size of the |
| 614 | // memory region. |
| 615 | // Returns info on the first memory region at or after |address|, including |
| 616 | // resident memory and share mode. |
| 617 | // |size| and |info| are output parameters, only valid on Success. |
| 618 | BASE_EXPORT MachVMRegionResult GetBasicInfo(mach_port_t task, |
| 619 | mach_vm_size_t* size, |
| 620 | mach_vm_address_t* address, |
| 621 | vm_region_basic_info_64* info); |
| Gyuyoung Kim | 52e933789 | 2023-04-20 15:08:41 | [diff] [blame] | 622 | |
| Gyuyoung Kim | 52e933789 | 2023-04-20 15:08:41 | [diff] [blame] | 623 | // Returns info on the first memory region at or after |address|, including |
| 624 | // resident memory and share mode. On Success, |size| reflects the size of the |
| 625 | // memory region. |
| 626 | // |size| and |info| are output parameters, only valid on Success. |
| 627 | // |address| is an in-out parameter, than represents both the address to start |
| 628 | // looking, and the start address of the memory region. |
| 629 | BASE_EXPORT MachVMRegionResult GetTopInfo(mach_port_t task, |
| 630 | mach_vm_size_t* size, |
| 631 | mach_vm_address_t* address, |
| 632 | vm_region_top_info_data_t* info); |
| Gyuyoung Kim | 038291c | 2023-08-16 14:54:50 | [diff] [blame] | 633 | #endif // BUILDFLAG(IS_APPLE) |
| erikchen | 12531f2 | 2017-04-21 19:48:51 | [diff] [blame] | 634 | |
| [email protected] | 32f5e9a0 | 2013-05-23 12:59:54 | [diff] [blame] | 635 | } // namespace base |
| 636 | |
| 637 | #endif // BASE_PROCESS_PROCESS_METRICS_H_ |