Thanks to visit codestin.com
Credit goes to chromium.googlesource.com

blob: cf41bb5e1ba78d43c6016a08b01101b9ae4be9fb [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2013 The Chromium Authors
[email protected]32f5e9a02013-05-23 12:59:542// 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
avibeced7c2015-12-24 06:47:5911#include <stddef.h>
12#include <stdint.h>
13
thestig0df2bae82016-07-26 17:59:3614#include <memory>
Helmut Januschkabfa62f72024-04-04 15:18:3115#include <string_view>
[email protected]32f5e9a02013-05-23 12:59:5416
17#include "base/base_export.h"
Avi Drissmanc4404ffc2025-08-05 21:48:0618#include "base/byte_count.h"
Alex Attard42f0112025-11-13 20:03:5719#include "base/byte_size.h"
[email protected]669a09332013-08-30 22:59:1420#include "base/gtest_prod_util.h"
Keishi Hattori7c3c7182022-06-24 22:18:1421#include "base/memory/raw_ptr.h"
[email protected]dd4b51262013-07-25 21:38:2322#include "base/process/process_handle.h"
[email protected]8f9a3a52013-06-28 15:14:1823#include "base/time/time.h"
Joe Mason550eed62024-03-25 18:07:3124#include "base/types/expected.h"
Roman Sorokina8cf50eb62023-01-18 11:22:2625#include "base/values.h"
avibeced7c2015-12-24 06:47:5926#include "build/build_config.h"
[email protected]32f5e9a02013-05-23 12:59:5427
Xiaohan Wang37e81612022-01-15 18:27:0028#if BUILDFLAG(IS_APPLE)
[email protected]32f5e9a02013-05-23 12:59:5429#include <mach/mach.h>
Peter Kasting134ef9af2024-12-28 02:30:0930
erikchencd3e0e7b2015-10-01 22:53:5131#include "base/process/port_provider_mac.h"
erikchen12531f22017-04-21 19:48:5132
Xiaohan Wang37e81612022-01-15 18:27:0033#if !BUILDFLAG(IS_IOS)
erikchen12531f22017-04-21 19:48:5134#include <mach/mach_vm.h>
35#endif
[email protected]32f5e9a02013-05-23 12:59:5436#endif
37
Xiaohan Wang37e81612022-01-15 18:27:0038#if BUILDFLAG(IS_WIN)
stanisce73f1a42017-03-31 21:42:2239#include "base/win/scoped_handle.h"
Bruce Dawsonbfdc3fd2018-01-03 20:32:3640#include "base/win/windows_types.h"
stanisce73f1a42017-03-31 21:42:2241#endif
42
Xiaohan Wang37e81612022-01-15 18:27:0043#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
44 BUILDFLAG(IS_AIX)
Lei Zhangaecb6ff62021-05-14 20:23:3645#include <string>
46#include <utility>
47#include <vector>
48
Lei Zhangaecb6ff62021-05-14 20:23:3649#include "base/threading/platform_thread.h"
50#endif
51
[email protected]32f5e9a02013-05-23 12:59:5452namespace base {
53
Xiaohan Wang37e81612022-01-15 18:27:0054#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
Benoit Lize448ee882017-08-31 13:32:1255// 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.
60struct PageFaultCounts {
61 int64_t minor;
62 int64_t major;
63};
Xiaohan Wang37e81612022-01-15 18:27:0064#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
65 // BUILDFLAG(IS_ANDROID)
Benoit Lize448ee882017-08-31 13:32:1266
[email protected]32f5e9a02013-05-23 12:59:5467// Convert a POSIX timeval to microseconds.
avibeced7c2015-12-24 06:47:5968BASE_EXPORT int64_t TimeValToMicroseconds(const struct timeval& tv);
[email protected]32f5e9a02013-05-23 12:59:5469
Etienne Pierre-doray490c80f2024-12-05 00:30:1470enum class ProcessUsageError {
Joe Mason550eed62024-03-25 18:07:3171 // 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 Mason550eed62024-03-25 18:07:3178};
79
Etienne Pierre-doray490c80f2024-12-05 00:30:1480using ProcessCPUUsageError = ProcessUsageError;
81
82struct 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 Drissmanc4404ffc2025-08-05 21:48:06103 // TBD: https://crbug.com/41315025
Etienne Pierre-doray490c80f2024-12-05 00:30:14104};
105
erikchen52b7b6b2018-03-23 21:58:50106// Provides performance metrics for a specified process (CPU usage and IO
107// counters). Use CreateCurrentProcessMetrics() to get an instance for the
fdoray287874242015-11-12 01:12:32108// current process, or CreateProcessMetrics() to get an instance for an
109// arbitrary process. Then, access the information with the different get
[email protected]32f5e9a02013-05-23 12:59:54110// methods.
erikchen52b7b6b2018-03-23 21:58:50111//
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 Lieb72ef02021-05-11 19:52:27119// https://chromium.googlesource.com/chromium/src/+/HEAD/docs/README.md#Memory
[email protected]32f5e9a02013-05-23 12:59:54120class BASE_EXPORT ProcessMetrics {
121 public:
Peter Boström7319bbd2021-09-15 22:59:38122 ProcessMetrics(const ProcessMetrics&) = delete;
123 ProcessMetrics& operator=(const ProcessMetrics&) = delete;
124
[email protected]32f5e9a02013-05-23 12:59:54125 ~ProcessMetrics();
126
127 // Creates a ProcessMetrics for the specified process.
Xiaohan Wang37e81612022-01-15 18:27:00128#if !BUILDFLAG(IS_MAC)
thestig0df2bae82016-07-26 17:59:36129 static std::unique_ptr<ProcessMetrics> CreateProcessMetrics(
130 ProcessHandle process);
[email protected]32f5e9a02013-05-23 12:59:54131#else
[email protected]32f5e9a02013-05-23 12:59:54132
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.
thestig0df2bae82016-07-26 17:59:36136 static std::unique_ptr<ProcessMetrics> CreateProcessMetrics(
137 ProcessHandle process,
138 PortProvider* port_provider);
Xiaohan Wang37e81612022-01-15 18:27:00139#endif // !BUILDFLAG(IS_MAC)
[email protected]32f5e9a02013-05-23 12:59:54140
fdoray287874242015-11-12 01:12:32141 // Creates a ProcessMetrics for the current process. This a cross-platform
142 // convenience wrapper for CreateProcessMetrics().
thestig0df2bae82016-07-26 17:59:36143 static std::unique_ptr<ProcessMetrics> CreateCurrentProcessMetrics();
fdoray287874242015-11-12 01:12:32144
Etienne Pierre-doray490c80f2024-12-05 00:30:14145 // 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;
erikchend447bb62018-03-08 22:06:24155
Wez4ae8f292017-09-11 20:52:03156 // Returns the percentage of time spent executing, across all threads of the
Patrick Monette87b033b62022-08-24 20:06:12157 // 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%.
Wez4ae8f292017-09-11 20:52:03163 //
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 Monette87b033b62022-08-24 20:06:12169 [[nodiscard]] double GetPlatformIndependentCPUUsage(TimeDelta cumulative_cpu);
170
171 // Same as the above, but automatically calls GetCumulativeCPUUsage() to
Joe Masonba145282024-03-12 20:18:19172 // determine the current cumulative CPU. Returns nullopt if
173 // GetCumulativeCPUUsage() fails.
Joe Mason307893c2024-04-03 18:39:38174 base::expected<double, ProcessCPUUsageError> GetPlatformIndependentCPUUsage();
[email protected]32f5e9a02013-05-23 12:59:54175
Sigurdur Asgeirssoneb27eae72018-05-16 15:29:10176 // Returns the cumulative CPU usage across all threads of the process since
Joe Masonba145282024-03-12 20:18:19177 // 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 Mason307893c2024-04-03 18:39:38181 base::expected<TimeDelta, ProcessCPUUsageError> GetCumulativeCPUUsage();
Sigurdur Asgeirssoneb27eae72018-05-16 15:29:10182
Xiaohan Wang37e81612022-01-15 18:27:00183#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
184 BUILDFLAG(IS_AIX)
Eric Seckler9db213952020-06-12 08:48:19185 // 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 Secklerdbc29da2020-07-10 11:54:05191 // allocations between repeated calls to this method.
Eric Seckler9db213952020-06-12 08:48:19192 // NOTE: Currently only supported on Linux/Android.
193 using CPUUsagePerThread = std::vector<std::pair<PlatformThreadId, TimeDelta>>;
194 bool GetCumulativeCPUUsagePerThread(CPUUsagePerThread&);
Xiaohan Wang37e81612022-01-15 18:27:00195#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
196 // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX)
Eric Secklerdbc29da2020-07-10 11:54:05197
[email protected]ac6d0652014-01-14 00:06:37198 // Returns the number of average idle cpu wakeups per second since the last
199 // call.
200 int GetIdleWakeupsPerSecond();
201
Xiaohan Wang37e81612022-01-15 18:27:00202#if BUILDFLAG(IS_APPLE)
Leonard Greyd1fc0b42017-10-09 17:01:01203 // 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 Wang37e81612022-01-15 18:27:00219#if BUILDFLAG(IS_POSIX)
afakhry43b3bb772015-12-15 21:57:59220 // Returns the number of file descriptors currently open by the process, or
221 // -1 on error.
222 int GetOpenFdCount() const;
dcastagnaf454af4e2017-03-15 23:34:14223
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 Wang37e81612022-01-15 18:27:00227#endif // BUILDFLAG(IS_POSIX)
afakhry43b3bb772015-12-15 21:57:59228
Xiaohan Wang37e81612022-01-15 18:27:00229#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
Benoit Lize448ee882017-08-31 13:32:12230 // Minor and major page fault count as reported by /proc/[pid]/stat.
231 // Returns true for success.
232 bool GetPageFaultCounts(PageFaultCounts* counts) const;
Xiaohan Wang37e81612022-01-15 18:27:00233#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
234 // BUILDFLAG(IS_ANDROID)
hjdbae6b3b2017-05-17 04:18:05235
keishi12b598b92017-06-20 10:25:26236 // Returns total memory usage of malloc.
237 size_t GetMallocUsage();
238
[email protected]32f5e9a02013-05-23 12:59:54239 private:
Xiaohan Wang37e81612022-01-15 18:27:00240#if !BUILDFLAG(IS_MAC)
[email protected]32f5e9a02013-05-23 12:59:54241 explicit ProcessMetrics(ProcessHandle process);
242#else
243 ProcessMetrics(ProcessHandle process, PortProvider* port_provider);
Xiaohan Wang37e81612022-01-15 18:27:00244#endif // !BUILDFLAG(IS_MAC)
[email protected]32f5e9a02013-05-23 12:59:54245
Xiaohan Wang37e81612022-01-15 18:27:00246#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
247 BUILDFLAG(IS_AIX)
avibeced7c2015-12-24 06:47:59248 int CalculateIdleWakeupsPerSecond(uint64_t absolute_idle_wakeups);
thestig75844fdb2014-09-09 19:47:10249#endif
Xiaohan Wang37e81612022-01-15 18:27:00250#if BUILDFLAG(IS_APPLE)
Leonard Greyd1fc0b42017-10-09 17:01:01251 // 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 Kim7229950b2023-07-21 00:20:43255
256 // Queries the port provider if it's set.
Francois Doray7898890312024-02-05 18:24:26257 mach_port_t TaskForHandle(ProcessHandle process_handle) const;
Leonard Greyd1fc0b42017-10-09 17:01:01258#endif
thestig75844fdb2014-09-09 19:47:10259
Xiaohan Wang37e81612022-01-15 18:27:00260#if BUILDFLAG(IS_WIN)
stanisce73f1a42017-03-31 21:42:22261 win::ScopedHandle process_;
262#else
[email protected]32f5e9a02013-05-23 12:59:54263 ProcessHandle process_;
stanisce73f1a42017-03-31 21:42:22264#endif
[email protected]32f5e9a02013-05-23 12:59:54265
[email protected]32f5e9a02013-05-23 12:59:54266 // Used to store the previous times and CPU usage counts so we can
267 // compute the CPU usage between calls.
[email protected]e21c3322014-04-06 21:25:01268 TimeTicks last_cpu_time_;
Xiaohan Wang37e81612022-01-15 18:27:00269#if !BUILDFLAG(IS_FREEBSD) || !BUILDFLAG(IS_POSIX)
Sigurdur Asgeirssoneb27eae72018-05-16 15:29:10270 TimeDelta last_cumulative_cpu_;
Mostyn Bramley-Mooreaae96722018-03-24 13:38:48271#endif
[email protected]32f5e9a02013-05-23 12:59:54272
Xiaohan Wang37e81612022-01-15 18:27:00273#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
274 BUILDFLAG(IS_AIX)
[email protected]ac6d0652014-01-14 00:06:37275 // Same thing for idle wakeups.
[email protected]e21c3322014-04-06 21:25:01276 TimeTicks last_idle_wakeups_time_;
avibeced7c2015-12-24 06:47:59277 uint64_t last_absolute_idle_wakeups_;
thestiga0d051ed2014-09-08 21:41:17278#endif
[email protected]ac6d0652014-01-14 00:06:37279
Xiaohan Wang37e81612022-01-15 18:27:00280#if BUILDFLAG(IS_APPLE)
Leonard Greyd1fc0b42017-10-09 17:01:01281 // And same thing for package idle exit wakeups.
282 TimeTicks last_package_idle_wakeups_time_;
283 uint64_t last_absolute_package_idle_wakeups_;
Joe Masonf75bf182023-10-17 22:16:25284
285 // Works around a race condition when combining two task_info() calls to
286 // measure CPU time.
287 TimeDelta last_measured_cpu_;
Leonard Greyd1fc0b42017-10-09 17:01:01288#endif
Gyuyoung Kim7229950b2023-07-21 00:20:43289
290#if BUILDFLAG(IS_MAC)
291 raw_ptr<PortProvider> port_provider_;
292#endif // BUILDFLAG(IS_MAC)
[email protected]32f5e9a02013-05-23 12:59:54293};
294
295// Returns the memory committed by the system in KBytes.
296// Returns 0 if it can't compute the commit charge.
297BASE_EXPORT size_t GetSystemCommitCharge();
298
[email protected]103ff3512013-08-22 07:19:30299// 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.
cmumfordbf823182014-11-20 16:32:56301BASE_EXPORT size_t GetMaxFds();
[email protected]b9f44b22014-05-29 23:15:55302
Matthew Cary144069d2019-07-11 19:26:17303// Returns the maximum number of handles that can be open at once per process.
304BASE_EXPORT size_t GetHandleLimit();
305
Xiaohan Wang37e81612022-01-15 18:27:00306#if BUILDFLAG(IS_POSIX)
Bo Liu6f2ff42c2018-05-14 18:29:15307// 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.
310BASE_EXPORT void IncreaseFdLimitTo(unsigned int max_descriptors);
Xiaohan Wang37e81612022-01-15 18:27:00311#endif // BUILDFLAG(IS_POSIX)
[email protected]103ff3512013-08-22 07:19:30312
Xiaohan Wang37e81612022-01-15 18:27:00313#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 Drissmanc4404ffc2025-08-05 21:48:06316// 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.
georgesak7144e042015-07-29 17:11:42321//
mkolom01ac10b2017-03-22 01:47:29322// Total memory are available on all platforms that implement
georgesakae7209ae2015-08-10 20:40:09323// GetSystemMemoryInfo(). Total/free swap memory are available on all platforms
324// except on Mac. Buffers/cached/active_anon/inactive_anon/active_file/
mkolom01ac10b2017-03-22 01:47:29325// inactive_file/dirty/reclaimable/pswpin/pswpout/pgmajfault are available on
Kuo-Hsin Yang7cc65fc2020-10-12 14:02:27326// Linux/Android/Chrome OS. Shmem/slab are Chrome OS only.
Avi Drissmanc4404ffc2025-08-05 21:48:06327// Speculative/file_backed/purgeable are Mac and iOS only. Free is absent on
328// Windows (see "avail_phys" below).
329struct BASE_EXPORT SystemMemoryInfo {
330 SystemMemoryInfo();
331 SystemMemoryInfo(const SystemMemoryInfo& other);
332 SystemMemoryInfo& operator=(const SystemMemoryInfo& other);
georgesak7144e042015-07-29 17:11:42333
Alex Attard42f0112025-11-13 20:03:57334 // TODO(crbug.com/458489438): Migrate all generic ByteCount usages in
335 // base/system and base/memory to the new types.
Avi Drissmanc4404ffc2025-08-05 21:48:06336 ByteCount total;
georgesak7144e042015-07-29 17:11:42337
Xiaohan Wang37e81612022-01-15 18:27:00338#if !BUILDFLAG(IS_WIN)
Avi Drissmanc4404ffc2025-08-05 21:48:06339 ByteCount free;
mkolom01ac10b2017-03-22 01:47:29340#endif
341
Xiaohan Wang37e81612022-01-15 18:27:00342#if BUILDFLAG(IS_WIN)
mkolom01ac10b2017-03-22 01:47:29343 // "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 Drissmanc4404ffc2025-08-05 21:48:06348 ByteCount avail_phys;
mkolom01ac10b2017-03-22 01:47:29349#endif
350
Xiaohan Wang37e81612022-01-15 18:27:00351#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
352 BUILDFLAG(IS_AIX)
halliwellc2eb0f972016-06-17 19:04:52353 // 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.
mkolom01ac10b2017-03-22 01:47:29357 // Note: it includes _all_ file-backed memory (active + inactive).
Avi Drissmanc4404ffc2025-08-05 21:48:06358 ByteCount available;
halliwellc2eb0f972016-06-17 19:04:52359#endif
360
Xiaohan Wang37e81612022-01-15 18:27:00361#if !BUILDFLAG(IS_APPLE)
Avi Drissmanc4404ffc2025-08-05 21:48:06362 ByteCount swap_total;
363 ByteCount swap_free;
georgesak7144e042015-07-29 17:11:42364#endif
365
Xiaohan Wang37e81612022-01-15 18:27:00366#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
367 BUILDFLAG(IS_AIX) || BUILDFLAG(IS_FUCHSIA)
Avi Drissmanc4404ffc2025-08-05 21:48:06368 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 Wang37e81612022-01-15 18:27:00376#endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) ||
377 // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_AIX) BUILDFLAG(IS_FUCHSIA)
georgesak7144e042015-07-29 17:11:42378
Eric Willigers611cf54e2022-04-28 02:22:14379#if BUILDFLAG(IS_CHROMEOS)
Avi Drissmanc4404ffc2025-08-05 21:48:06380 ByteCount shmem;
381 ByteCount slab;
Eric Willigers611cf54e2022-04-28 02:22:14382#endif // BUILDFLAG(IS_CHROMEOS)
mkolom01ac10b2017-03-22 01:47:29383
Xiaohan Wang37e81612022-01-15 18:27:00384#if BUILDFLAG(IS_APPLE)
Avi Drissmanc4404ffc2025-08-05 21:48:06385 ByteCount speculative;
386 ByteCount file_backed;
387 ByteCount purgeable;
Xiaohan Wang37e81612022-01-15 18:27:00388#endif // BUILDFLAG(IS_APPLE)
Alex Attard42f0112025-11-13 20:03:57389
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;
georgesak7144e042015-07-29 17:11:42394};
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 Drissmanc4404ffc2025-08-05 21:48:06402BASE_EXPORT bool GetSystemMemoryInfo(SystemMemoryInfo* meminfo);
georgesak7144e042015-07-29 17:11:42403
Xiaohan Wang37e81612022-01-15 18:27:00404#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) ||
405 // BUILDFLAG(IS_CHROMEOS) BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX) ||
406 // BUILDFLAG(IS_FUCHSIA)
georgesak7144e042015-07-29 17:11:42407
Xiaohan Wang37e81612022-01-15 18:27:00408#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
409 BUILDFLAG(IS_AIX)
[email protected]32f5e9a02013-05-23 12:59:54410// 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 Januschkabfa62f72024-04-04 15:18:31413BASE_EXPORT int ParseProcStatCPU(std::string_view input);
[email protected]32f5e9a02013-05-23 12:59:54414
[email protected]103ff3512013-08-22 07:19:30415// 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 Kasting25acd5942022-07-07 17:45:15419BASE_EXPORT int64_t GetNumberOfThreads(ProcessHandle process);
[email protected]103ff3512013-08-22 07:19:30420
421// /proc/self/exe refers to the current executable.
422BASE_EXPORT extern const char kProcSelfExe[];
423
[email protected]70baebc2013-11-02 16:58:44424// Parses a string containing the contents of /proc/meminfo
425// returns true on success or false for a parsing error
thestigbc11dd62017-05-04 18:55:08426// Exposed for testing.
Helmut Januschkabfa62f72024-04-04 15:18:31427BASE_EXPORT bool ParseProcMeminfo(std::string_view input,
Avi Drissmanc4404ffc2025-08-05 21:48:06428 SystemMemoryInfo* meminfo);
[email protected]70baebc2013-11-02 16:58:44429
Joe Mason87c33f12024-02-09 15:47:04430// 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.
433BASE_EXPORT size_t
Avi Drissmanc4404ffc2025-08-05 21:48:06434GetSystemCommitChargeFromMeminfo(const SystemMemoryInfo& meminfo);
Joe Mason87c33f12024-02-09 15:47:04435
Kenichi Ishibashi44871522017-10-23 07:12:19436// Data from /proc/vmstat.
437struct BASE_EXPORT VmStatInfo {
Peter Kasting6a4bf14c2022-07-13 14:53:33438 uint64_t pswpin = 0;
439 uint64_t pswpout = 0;
440 uint64_t pgmajfault = 0;
441 uint64_t oom_kill = 0;
Kenichi Ishibashi44871522017-10-23 07:12:19442};
443
444// Retrieves data from /proc/vmstat about system-wide vm operations.
445// Fills in the provided |vmstat| structure. Returns true on success.
446BASE_EXPORT bool GetVmStatInfo(VmStatInfo* vmstat);
447
[email protected]70baebc2013-11-02 16:58:44448// Parses a string containing the contents of /proc/vmstat
449// returns true on success or false for a parsing error
thestigbc11dd62017-05-04 18:55:08450// Exposed for testing.
Helmut Januschkabfa62f72024-04-04 15:18:31451BASE_EXPORT bool ParseProcVmstat(std::string_view input, VmStatInfo* vmstat);
[email protected]70baebc2013-11-02 16:58:44452
[email protected]669a09332013-08-30 22:59:14453// Data from /proc/diskstats about system-wide disk I/O.
454struct BASE_EXPORT SystemDiskInfo {
455 SystemDiskInfo();
Peter Kastinge08ca13342021-07-08 02:46:57456 SystemDiskInfo(const SystemDiskInfo&);
457 SystemDiskInfo& operator=(const SystemDiskInfo&);
[email protected]669a09332013-08-30 22:59:14458
Kenichi Ishibashi44871522017-10-23 07:12:19459 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]669a09332013-08-30 22:59:14470};
471
thestiga0d051ed2014-09-08 21:41:17472// Checks whether the candidate string is a valid disk name, [hsv]d[a-z]+
[email protected]669a09332013-08-30 22:59:14473// for a generic disk or mmcblk[0-9]+ for the MMC case.
474// Names of disk partitions (e.g. sda1) are not valid.
Helmut Januschkabfa62f72024-04-04 15:18:31475BASE_EXPORT bool IsValidDiskName(std::string_view candidate);
[email protected]669a09332013-08-30 22:59:14476
477// Retrieves data from /proc/diskstats about system-wide disk I/O.
478// Fills in the provided |diskinfo| structure. Returns true on success.
479BASE_EXPORT bool GetSystemDiskInfo(SystemDiskInfo* diskinfo);
thomasandersonfc4688ab2016-09-10 01:19:43480
481// Returns the amount of time spent in user space since boot across all CPUs.
482BASE_EXPORT TimeDelta GetUserCpuTimeSinceBoot();
Kenichi Ishibashi44871522017-10-23 07:12:19483
Xiaohan Wang37e81612022-01-15 18:27:00484#endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
485 // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX)
[email protected]32f5e9a02013-05-23 12:59:54486
Eric Willigers611cf54e2022-04-28 02:22:14487#if BUILDFLAG(IS_CHROMEOS)
[email protected]f4134782013-08-29 21:25:20488// Data from files in directory /sys/block/zram0 about ZRAM usage.
489struct BASE_EXPORT SwapInfo {
490 SwapInfo()
491 : num_reads(0),
492 num_writes(0),
493 compr_data_size(0),
494 orig_data_size(0),
Peter Kasting134ef9af2024-12-28 02:30:09495 mem_used_total(0) {}
[email protected]f4134782013-08-29 21:25:20496
Kenichi Ishibashi44871522017-10-23 07:12:19497 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]f4134782013-08-29 21:25:20502};
503
Chung-Sheng Wu838f843b2017-07-21 04:17:58504// 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 Januschkabfa62f72024-04-04 15:18:31508BASE_EXPORT bool ParseZramMmStat(std::string_view mm_stat_data,
509 SwapInfo* swap_info);
Chung-Sheng Wu838f843b2017-07-21 04:17:58510
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 Januschkabfa62f72024-04-04 15:18:31515BASE_EXPORT bool ParseZramStat(std::string_view stat_data, SwapInfo* swap_info);
Chung-Sheng Wu838f843b2017-07-21 04:17:58516
[email protected]f4134782013-08-29 21:25:20517// In ChromeOS, reads files from /sys/block/zram0 that contain ZRAM usage data.
518// Fills in the provided |swap_data| structure.
Chung-Sheng Wu838f843b2017-07-21 04:17:58519// Returns true on success or false for a parsing error.
520BASE_EXPORT bool GetSwapInfo(SwapInfo* swap_info);
Kuo-Hsin Yang7cc65fc2020-10-12 14:02:27521
522// Data about GPU memory usage. These fields will be -1 if not supported.
523struct BASE_EXPORT GraphicsMemoryInfoKB {
Kuo-Hsin Yang7cc65fc2020-10-12 14:02:27524 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.
532BASE_EXPORT bool GetGraphicsMemoryInfo(GraphicsMemoryInfoKB* gpu_meminfo);
533
Eric Willigers611cf54e2022-04-28 02:22:14534#endif // BUILDFLAG(IS_CHROMEOS)
[email protected]f4134782013-08-29 21:25:20535
Etienne Bergeron0b9d2b62018-08-15 20:34:10536struct BASE_EXPORT SystemPerformanceInfo {
537 SystemPerformanceInfo();
538 SystemPerformanceInfo(const SystemPerformanceInfo& other);
Arthur Eubanks08f7b0542022-09-16 00:53:01539 SystemPerformanceInfo& operator=(const SystemPerformanceInfo& other);
Etienne Bergeron0b9d2b62018-08-15 20:34:10540
Etienne Bergeron0b9d2b62018-08-15 20:34:10541 // 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 Marchand57c036da2018-10-04 20:53:20559 // 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 Bergeron0b9d2b62018-08-15 20:34:10566};
567
568// Retrieves performance counters from the operating system.
569// Fills in the provided |info| structure. Returns true on success.
570BASE_EXPORT bool GetSystemPerformanceInfo(SystemPerformanceInfo* info);
571
[email protected]14b4f102013-08-22 01:12:19572// 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 Marchanddbe43bab2019-02-06 18:25:51575class BASE_EXPORT SystemMetrics {
[email protected]14b4f102013-08-22 01:12:19576 public:
[email protected]49b0cf82013-09-03 23:46:54577 SystemMetrics();
[email protected]14b4f102013-08-22 01:12:19578
579 static SystemMetrics Sample();
580
[email protected]14b4f102013-08-22 01:12:19581 private:
[email protected]669a09332013-08-30 22:59:14582 FRIEND_TEST_ALL_PREFIXES(SystemMetricsTest, SystemMetrics);
583
[email protected]14b4f102013-08-22 01:12:19584 size_t committed_memory_;
Xiaohan Wang37e81612022-01-15 18:27:00585#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
Avi Drissmanc4404ffc2025-08-05 21:48:06586 SystemMemoryInfo memory_info_;
Kenichi Ishibashi44871522017-10-23 07:12:19587 VmStatInfo vmstat_info_;
[email protected]49b0cf82013-09-03 23:46:54588 SystemDiskInfo disk_info_;
589#endif
Eric Willigers611cf54e2022-04-28 02:22:14590#if BUILDFLAG(IS_CHROMEOS)
[email protected]49b0cf82013-09-03 23:46:54591 SwapInfo swap_info_;
Kuo-Hsin Yang7cc65fc2020-10-12 14:02:27592 GraphicsMemoryInfoKB gpu_memory_info_;
[email protected]14b4f102013-08-22 01:12:19593#endif
Xiaohan Wang37e81612022-01-15 18:27:00594#if BUILDFLAG(IS_WIN)
Etienne Bergeron0b9d2b62018-08-15 20:34:10595 SystemPerformanceInfo performance_;
596#endif
[email protected]14b4f102013-08-22 01:12:19597};
598
Gyuyoung Kim52e9337892023-04-20 15:08:41599#if BUILDFLAG(IS_APPLE)
erikchen12531f22017-04-21 19:48:51600enum 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
erikchen12531f22017-04-21 19:48:51613// 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.
618BASE_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 Kim52e9337892023-04-20 15:08:41622
Gyuyoung Kim52e9337892023-04-20 15:08:41623// 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.
629BASE_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 Kim038291c2023-08-16 14:54:50633#endif // BUILDFLAG(IS_APPLE)
erikchen12531f22017-04-21 19:48:51634
[email protected]32f5e9a02013-05-23 12:59:54635} // namespace base
636
637#endif // BASE_PROCESS_PROCESS_METRICS_H_