• 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 // 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 
11 #include <stddef.h>
12 #include <stdint.h>
13 
14 #include <memory>
15 
16 #include "base/base_export.h"
17 #include "base/gtest_prod_util.h"
18 #include "base/memory/raw_ptr.h"
19 #include "base/process/process_handle.h"
20 #include "base/strings/string_piece.h"
21 #include "base/time/time.h"
22 #include "base/values.h"
23 #include "build/build_config.h"
24 
25 #if BUILDFLAG(IS_APPLE)
26 #include <mach/mach.h>
27 #include "base/process/port_provider_mac.h"
28 
29 #if !BUILDFLAG(IS_IOS)
30 #include <mach/mach_vm.h>
31 #endif
32 #endif
33 
34 #if BUILDFLAG(IS_WIN)
35 #include "base/win/scoped_handle.h"
36 #include "base/win/windows_types.h"
37 #endif
38 
39 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
40     BUILDFLAG(IS_AIX)
41 #include <string>
42 #include <utility>
43 #include <vector>
44 
45 #include "base/threading/platform_thread.h"
46 #endif
47 
48 namespace base {
49 
50 // Full declaration is in process_metrics_iocounters.h.
51 struct IoCounters;
52 
53 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
54 // Minor and major page fault counts since the process creation.
55 // Both counts are process-wide, and exclude child processes.
56 //
57 // minor: Number of page faults that didn't require disk IO.
58 // major: Number of page faults that required disk IO.
59 struct PageFaultCounts {
60   int64_t minor;
61   int64_t major;
62 };
63 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
64         // BUILDFLAG(IS_ANDROID)
65 
66 // Convert a POSIX timeval to microseconds.
67 BASE_EXPORT int64_t TimeValToMicroseconds(const struct timeval& tv);
68 
69 // Provides performance metrics for a specified process (CPU usage and IO
70 // counters). Use CreateCurrentProcessMetrics() to get an instance for the
71 // current process, or CreateProcessMetrics() to get an instance for an
72 // arbitrary process. Then, access the information with the different get
73 // methods.
74 //
75 // This class exposes a few platform-specific APIs for parsing memory usage, but
76 // these are not intended to generalize to other platforms, since the memory
77 // models differ substantially.
78 //
79 // To obtain consistent memory metrics, use the memory_instrumentation service.
80 //
81 // For further documentation on memory, see
82 // https://chromium.googlesource.com/chromium/src/+/HEAD/docs/README.md#Memory
83 class BASE_EXPORT ProcessMetrics {
84  public:
85   ProcessMetrics(const ProcessMetrics&) = delete;
86   ProcessMetrics& operator=(const ProcessMetrics&) = delete;
87 
88   ~ProcessMetrics();
89 
90   // Creates a ProcessMetrics for the specified process.
91 #if !BUILDFLAG(IS_MAC)
92   static std::unique_ptr<ProcessMetrics> CreateProcessMetrics(
93       ProcessHandle process);
94 #else
95 
96   // The port provider needs to outlive the ProcessMetrics object returned by
97   // this function. If NULL is passed as provider, the returned object
98   // only returns valid metrics if |process| is the current process.
99   static std::unique_ptr<ProcessMetrics> CreateProcessMetrics(
100       ProcessHandle process,
101       PortProvider* port_provider);
102 #endif  // !BUILDFLAG(IS_MAC)
103 
104   // Creates a ProcessMetrics for the current process. This a cross-platform
105   // convenience wrapper for CreateProcessMetrics().
106   static std::unique_ptr<ProcessMetrics> CreateCurrentProcessMetrics();
107 
108 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
109   // Resident Set Size is a Linux/Android specific memory concept. Do not
110   // attempt to extend this to other platforms.
111   BASE_EXPORT size_t GetResidentSetSize() const;
112 #endif
113 
114   // Returns the percentage of time spent executing, across all threads of the
115   // process, in the interval since the last time the method was called, using
116   // the current |cumulative_cpu|. Since this considers the total execution time
117   // across all threads in a process, the result can easily exceed 100% in
118   // multi-thread processes running on multi-core systems. In general the result
119   // is therefore a value in the range 0% to
120   // SysInfo::NumberOfProcessors() * 100%.
121   //
122   // To obtain the percentage of total available CPU resources consumed by this
123   // process over the interval, the caller must divide by NumberOfProcessors().
124   //
125   // Since this API measures usage over an interval, it will return zero on the
126   // first call, and an actual value only on the second and subsequent calls.
127   [[nodiscard]] double GetPlatformIndependentCPUUsage(TimeDelta cumulative_cpu);
128 
129   // Same as the above, but automatically calls GetCumulativeCPUUsage() to
130   // determine the current cumulative CPU.
131   [[nodiscard]] double GetPlatformIndependentCPUUsage();
132 
133   // Returns the cumulative CPU usage across all threads of the process since
134   // process start. In case of multi-core processors, a process can consume CPU
135   // at a rate higher than wall-clock time, e.g. two cores at full utilization
136   // will result in a time delta of 2 seconds/per 1 wall-clock second.
137   [[nodiscard]] TimeDelta GetCumulativeCPUUsage();
138 
139 #if BUILDFLAG(IS_WIN)
140   // TODO(pmonette): Remove the precise version of the CPU usage functions once
141   // we're validated that they are indeed better than the regular version above
142   // and that they can replace the old implementation.
143 
144   // Returns the percentage of time spent executing, across all threads of the
145   // process, in the interval since the last time the method was called, using
146   // the current |cumulative_cpu|.
147   //
148   // Same as GetPlatformIndependentCPUUSage() but implemented using
149   // `QueryProcessCycleTime` for higher precision.
150   [[nodiscard]] double GetPreciseCPUUsage(TimeDelta cumulative_cpu);
151 
152   // Same as the above, but automatically calls GetPreciseCumulativeCPUUsage()
153   // to determine the current cumulative CPU.
154   [[nodiscard]] double GetPreciseCPUUsage();
155 
156   // Returns the cumulative CPU usage across all threads of the process since
157   // process start. In case of multi-core processors, a process can consume CPU
158   // at a rate higher than wall-clock time, e.g. two cores at full utilization
159   // will result in a time delta of 2 seconds/per 1 wall-clock second.
160   //
161   // This is implemented using `QueryProcessCycleTime` for higher precision.
162   [[nodiscard]] TimeDelta GetPreciseCumulativeCPUUsage();
163 #endif  // BUILDFLAG(IS_WIN)
164 
165 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
166     BUILDFLAG(IS_AIX)
167   // Emits the cumulative CPU usage for all currently active threads since they
168   // were started into the output parameter (replacing its current contents).
169   // Threads that have already terminated will not be reported. Thus, the sum of
170   // these times may not equal the value returned by GetCumulativeCPUUsage().
171   // Returns false on failure. We return the usage via an output parameter to
172   // allow reuse of CPUUsagePerThread's std::vector by the caller, e.g. to avoid
173   // allocations between repeated calls to this method.
174   // NOTE: Currently only supported on Linux/Android.
175   using CPUUsagePerThread = std::vector<std::pair<PlatformThreadId, TimeDelta>>;
176   bool GetCumulativeCPUUsagePerThread(CPUUsagePerThread&);
177 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
178         // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX)
179 
180   // Returns the number of average idle cpu wakeups per second since the last
181   // call.
182   int GetIdleWakeupsPerSecond();
183 
184 #if BUILDFLAG(IS_APPLE)
185   // Returns the number of average "package idle exits" per second, which have
186   // a higher energy impact than a regular wakeup, since the last call.
187   //
188   // From the powermetrics man page:
189   // "With the exception of some Mac Pro systems, Mac and
190   // iOS systems are typically single package systems, wherein all CPUs are
191   // part of a single processor complex (typically a single IC die) with shared
192   // logic that can include (depending on system specifics) shared last level
193   // caches, an integrated memory controller etc. When all CPUs in the package
194   // are idle, the hardware can power-gate significant portions of the shared
195   // logic in addition to each individual processor's logic, as well as take
196   // measures such as placing DRAM in to self-refresh (also referred to as
197   // auto-refresh), place interconnects into lower-power states etc"
198   int GetPackageIdleWakeupsPerSecond();
199 
200   // Returns "Energy Impact", a synthetic power estimation metric displayed by
201   // macOS in Activity Monitor and the battery menu.
202   int GetEnergyImpact();
203 #endif
204 
205   // Retrieves accounting information for all I/O operations performed by the
206   // process.
207   // If IO information is retrieved successfully, the function returns true
208   // and fills in the IO_COUNTERS passed in. The function returns false
209   // otherwise.
210   bool GetIOCounters(IoCounters* io_counters) const;
211 
212   // Returns the cumulative disk usage in bytes across all threads of the
213   // process since process start.
214   uint64_t GetCumulativeDiskUsageInBytes();
215 
216 #if BUILDFLAG(IS_POSIX)
217   // Returns the number of file descriptors currently open by the process, or
218   // -1 on error.
219   int GetOpenFdCount() const;
220 
221   // Returns the soft limit of file descriptors that can be opened by the
222   // process, or -1 on error.
223   int GetOpenFdSoftLimit() const;
224 #endif  // BUILDFLAG(IS_POSIX)
225 
226 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
227   // Bytes of swap as reported by /proc/[pid]/status.
228   uint64_t GetVmSwapBytes() const;
229 
230   // Minor and major page fault count as reported by /proc/[pid]/stat.
231   // Returns true for success.
232   bool GetPageFaultCounts(PageFaultCounts* counts) const;
233 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
234         // BUILDFLAG(IS_ANDROID)
235 
236   // Returns total memory usage of malloc.
237   size_t GetMallocUsage();
238 
239  private:
240 #if !BUILDFLAG(IS_MAC)
241   explicit ProcessMetrics(ProcessHandle process);
242 #else
243   ProcessMetrics(ProcessHandle process, PortProvider* port_provider);
244 #endif  // !BUILDFLAG(IS_MAC)
245 
246 #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
247     BUILDFLAG(IS_AIX)
248   int CalculateIdleWakeupsPerSecond(uint64_t absolute_idle_wakeups);
249 #endif
250 #if BUILDFLAG(IS_APPLE)
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);
255 #endif
256 
257 #if BUILDFLAG(IS_WIN)
258   win::ScopedHandle process_;
259 #else
260   ProcessHandle process_;
261 #endif
262 
263   // Used to store the previous times and CPU usage counts so we can
264   // compute the CPU usage between calls.
265   TimeTicks last_cpu_time_;
266 #if !BUILDFLAG(IS_FREEBSD) || !BUILDFLAG(IS_POSIX)
267   TimeDelta last_cumulative_cpu_;
268 #endif
269 
270 #if BUILDFLAG(IS_WIN)
271   TimeTicks last_cpu_time_for_precise_cpu_usage_;
272   TimeDelta last_precise_cumulative_cpu_;
273 #endif
274 
275 #if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
276     BUILDFLAG(IS_AIX)
277   // Same thing for idle wakeups.
278   TimeTicks last_idle_wakeups_time_;
279   uint64_t last_absolute_idle_wakeups_;
280 #endif
281 
282 #if BUILDFLAG(IS_APPLE)
283   // And same thing for package idle exit wakeups.
284   TimeTicks last_package_idle_wakeups_time_;
285   uint64_t last_absolute_package_idle_wakeups_;
286   double last_energy_impact_;
287   // In mach_absolute_time units.
288   uint64_t last_energy_impact_time_;
289 #endif
290 
291 #if BUILDFLAG(IS_MAC)
292   // Queries the port provider if it's set.
293   mach_port_t TaskForPid(ProcessHandle process) const;
294 
295   raw_ptr<PortProvider> port_provider_;
296 #endif  // BUILDFLAG(IS_MAC)
297 };
298 
299 // Returns the memory committed by the system in KBytes.
300 // Returns 0 if it can't compute the commit charge.
301 BASE_EXPORT size_t GetSystemCommitCharge();
302 
303 // Returns the maximum number of file descriptors that can be open by a process
304 // at once. If the number is unavailable, a conservative best guess is returned.
305 BASE_EXPORT size_t GetMaxFds();
306 
307 // Returns the maximum number of handles that can be open at once per process.
308 BASE_EXPORT size_t GetHandleLimit();
309 
310 #if BUILDFLAG(IS_POSIX)
311 // Increases the file descriptor soft limit to |max_descriptors| or the OS hard
312 // limit, whichever is lower. If the limit is already higher than
313 // |max_descriptors|, then nothing happens.
314 BASE_EXPORT void IncreaseFdLimitTo(unsigned int max_descriptors);
315 #endif  // BUILDFLAG(IS_POSIX)
316 
317 #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) ||      \
318     BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX) || \
319     BUILDFLAG(IS_FUCHSIA)
320 // Data about system-wide memory consumption. Values are in KB. Available on
321 // Windows, Mac, Linux, Android and Chrome OS.
322 //
323 // Total memory are available on all platforms that implement
324 // GetSystemMemoryInfo(). Total/free swap memory are available on all platforms
325 // except on Mac. Buffers/cached/active_anon/inactive_anon/active_file/
326 // inactive_file/dirty/reclaimable/pswpin/pswpout/pgmajfault are available on
327 // Linux/Android/Chrome OS. Shmem/slab are Chrome OS only.
328 // Speculative/file_backed/purgeable are Mac and iOS only.
329 // Free is absent on Windows (see "avail_phys" below).
330 struct BASE_EXPORT SystemMemoryInfoKB {
331   SystemMemoryInfoKB();
332   SystemMemoryInfoKB(const SystemMemoryInfoKB& other);
333   SystemMemoryInfoKB& operator=(const SystemMemoryInfoKB& other);
334 
335   // Serializes the platform specific fields to value.
336   Value::Dict ToDict() const;
337 
338   int total = 0;
339 
340 #if !BUILDFLAG(IS_WIN)
341   int free = 0;
342 #endif
343 
344 #if BUILDFLAG(IS_WIN)
345   // "This is the amount of physical memory that can be immediately reused
346   // without having to write its contents to disk first. It is the sum of the
347   // size of the standby, free, and zero lists." (MSDN).
348   // Standby: not modified pages of physical ram (file-backed memory) that are
349   // not actively being used.
350   int avail_phys = 0;
351 #endif
352 
353 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
354     BUILDFLAG(IS_AIX)
355   // This provides an estimate of available memory as described here:
356   // https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
357   // NOTE: this is ONLY valid in kernels 3.14 and up.  Its value will always
358   // be 0 in earlier kernel versions.
359   // Note: it includes _all_ file-backed memory (active + inactive).
360   int available = 0;
361 #endif
362 
363 #if !BUILDFLAG(IS_APPLE)
364   int swap_total = 0;
365   int swap_free = 0;
366 #endif
367 
368 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \
369     BUILDFLAG(IS_AIX) || BUILDFLAG(IS_FUCHSIA)
370   int buffers = 0;
371   int cached = 0;
372   int active_anon = 0;
373   int inactive_anon = 0;
374   int active_file = 0;
375   int inactive_file = 0;
376   int dirty = 0;
377   int reclaimable = 0;
378 #endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) ||
379         // BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_AIX) BUILDFLAG(IS_FUCHSIA)
380 
381 #if BUILDFLAG(IS_CHROMEOS)
382   int shmem = 0;
383   int slab = 0;
384 #endif  // BUILDFLAG(IS_CHROMEOS)
385 
386 #if BUILDFLAG(IS_APPLE)
387   int speculative = 0;
388   int file_backed = 0;
389   int purgeable = 0;
390 #endif  // BUILDFLAG(IS_APPLE)
391 };
392 
393 // On Linux/Android/Chrome OS, system-wide memory consumption data is parsed
394 // from /proc/meminfo and /proc/vmstat. On Windows/Mac, it is obtained using
395 // system API calls.
396 //
397 // Fills in the provided |meminfo| structure. Returns true on success.
398 // Exposed for memory debugging widget.
399 BASE_EXPORT bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo);
400 
401 #endif  // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) ||
402         // BUILDFLAG(IS_CHROMEOS) BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX) ||
403         // BUILDFLAG(IS_FUCHSIA)
404 
405 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID) || \
406     BUILDFLAG(IS_AIX)
407 // Parse the data found in /proc/<pid>/stat and return the sum of the
408 // CPU-related ticks.  Returns -1 on parse error.
409 // Exposed for testing.
410 BASE_EXPORT int ParseProcStatCPU(StringPiece input);
411 
412 // Get the number of threads of |process| as available in /proc/<pid>/stat.
413 // This should be used with care as no synchronization with running threads is
414 // done. This is mostly useful to guarantee being single-threaded.
415 // Returns 0 on failure.
416 BASE_EXPORT int64_t GetNumberOfThreads(ProcessHandle process);
417 
418 // /proc/self/exe refers to the current executable.
419 BASE_EXPORT extern const char kProcSelfExe[];
420 
421 // Parses a string containing the contents of /proc/meminfo
422 // returns true on success or false for a parsing error
423 // Exposed for testing.
424 BASE_EXPORT bool ParseProcMeminfo(StringPiece input,
425                                   SystemMemoryInfoKB* meminfo);
426 
427 // Data from /proc/vmstat.
428 struct BASE_EXPORT VmStatInfo {
429   // Serializes the platform specific fields to value.
430   Value::Dict ToDict() const;
431 
432   uint64_t pswpin = 0;
433   uint64_t pswpout = 0;
434   uint64_t pgmajfault = 0;
435   uint64_t oom_kill = 0;
436 };
437 
438 // Retrieves data from /proc/vmstat about system-wide vm operations.
439 // Fills in the provided |vmstat| structure. Returns true on success.
440 BASE_EXPORT bool GetVmStatInfo(VmStatInfo* vmstat);
441 
442 // Parses a string containing the contents of /proc/vmstat
443 // returns true on success or false for a parsing error
444 // Exposed for testing.
445 BASE_EXPORT bool ParseProcVmstat(StringPiece input, VmStatInfo* vmstat);
446 
447 // Data from /proc/diskstats about system-wide disk I/O.
448 struct BASE_EXPORT SystemDiskInfo {
449   SystemDiskInfo();
450   SystemDiskInfo(const SystemDiskInfo&);
451   SystemDiskInfo& operator=(const SystemDiskInfo&);
452 
453   // Serializes the platform specific fields to value.
454   Value::Dict ToDict() const;
455 
456   uint64_t reads = 0;
457   uint64_t reads_merged = 0;
458   uint64_t sectors_read = 0;
459   uint64_t read_time = 0;
460   uint64_t writes = 0;
461   uint64_t writes_merged = 0;
462   uint64_t sectors_written = 0;
463   uint64_t write_time = 0;
464   uint64_t io = 0;
465   uint64_t io_time = 0;
466   uint64_t weighted_io_time = 0;
467 };
468 
469 // Checks whether the candidate string is a valid disk name, [hsv]d[a-z]+
470 // for a generic disk or mmcblk[0-9]+ for the MMC case.
471 // Names of disk partitions (e.g. sda1) are not valid.
472 BASE_EXPORT bool IsValidDiskName(StringPiece candidate);
473 
474 // Retrieves data from /proc/diskstats about system-wide disk I/O.
475 // Fills in the provided |diskinfo| structure. Returns true on success.
476 BASE_EXPORT bool GetSystemDiskInfo(SystemDiskInfo* diskinfo);
477 
478 // Returns the amount of time spent in user space since boot across all CPUs.
479 BASE_EXPORT TimeDelta GetUserCpuTimeSinceBoot();
480 
481 #endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
482         // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_AIX)
483 
484 #if BUILDFLAG(IS_CHROMEOS)
485 // Data from files in directory /sys/block/zram0 about ZRAM usage.
486 struct BASE_EXPORT SwapInfo {
SwapInfoSwapInfo487   SwapInfo()
488       : num_reads(0),
489         num_writes(0),
490         compr_data_size(0),
491         orig_data_size(0),
492         mem_used_total(0) {
493   }
494 
495   // Serializes the platform specific fields to value.
496   Value::Dict ToDict() const;
497 
498   uint64_t num_reads = 0;
499   uint64_t num_writes = 0;
500   uint64_t compr_data_size = 0;
501   uint64_t orig_data_size = 0;
502   uint64_t mem_used_total = 0;
503 };
504 
505 // Parses a string containing the contents of /sys/block/zram0/mm_stat.
506 // This should be used for the new ZRAM sysfs interfaces.
507 // Returns true on success or false for a parsing error.
508 // Exposed for testing.
509 BASE_EXPORT bool ParseZramMmStat(StringPiece mm_stat_data, SwapInfo* swap_info);
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.
515 BASE_EXPORT bool ParseZramStat(StringPiece stat_data, SwapInfo* swap_info);
516 
517 // In ChromeOS, reads files from /sys/block/zram0 that contain ZRAM usage data.
518 // Fills in the provided |swap_data| structure.
519 // Returns true on success or false for a parsing error.
520 BASE_EXPORT bool GetSwapInfo(SwapInfo* swap_info);
521 
522 // Data about GPU memory usage. These fields will be -1 if not supported.
523 struct BASE_EXPORT GraphicsMemoryInfoKB {
524   // Serializes the platform specific fields to value.
525   Value::Dict ToDict() const;
526 
527   int gpu_objects = -1;
528   int64_t gpu_memory_size = -1;
529 };
530 
531 // Report on Chrome OS graphics memory. Returns true on success.
532 // /run/debugfs_gpu is a bind mount into /sys/kernel/debug and synchronously
533 // reading the in-memory files in /sys is fast in most cases. On platform that
534 // reading the graphics memory info is slow, this function returns false.
535 BASE_EXPORT bool GetGraphicsMemoryInfo(GraphicsMemoryInfoKB* gpu_meminfo);
536 
537 #endif  // BUILDFLAG(IS_CHROMEOS)
538 
539 struct BASE_EXPORT SystemPerformanceInfo {
540   SystemPerformanceInfo();
541   SystemPerformanceInfo(const SystemPerformanceInfo& other);
542   SystemPerformanceInfo& operator=(const SystemPerformanceInfo& other);
543 
544   // Serializes the platform specific fields to value.
545   Value::Dict ToDict() const;
546 
547   // Total idle time of all processes in the system (units of 100 ns).
548   uint64_t idle_time = 0;
549   // Number of bytes read.
550   uint64_t read_transfer_count = 0;
551   // Number of bytes written.
552   uint64_t write_transfer_count = 0;
553   // Number of bytes transferred (e.g. DeviceIoControlFile)
554   uint64_t other_transfer_count = 0;
555   // The amount of read operations.
556   uint64_t read_operation_count = 0;
557   // The amount of write operations.
558   uint64_t write_operation_count = 0;
559   // The amount of other operations.
560   uint64_t other_operation_count = 0;
561   // The number of pages written to the system's pagefiles.
562   uint64_t pagefile_pages_written = 0;
563   // The number of write operations performed on the system's pagefiles.
564   uint64_t pagefile_pages_write_ios = 0;
565   // The number of pages of physical memory available to processes running on
566   // the system.
567   uint64_t available_pages = 0;
568   // The number of pages read from disk to resolve page faults.
569   uint64_t pages_read = 0;
570   // The number of read operations initiated to resolve page faults.
571   uint64_t page_read_ios = 0;
572 };
573 
574 // Retrieves performance counters from the operating system.
575 // Fills in the provided |info| structure. Returns true on success.
576 BASE_EXPORT bool GetSystemPerformanceInfo(SystemPerformanceInfo* info);
577 
578 // Collects and holds performance metrics for system memory and disk.
579 // Provides functionality to retrieve the data on various platforms and
580 // to serialize the stored data.
581 class BASE_EXPORT SystemMetrics {
582  public:
583   SystemMetrics();
584 
585   static SystemMetrics Sample();
586 
587   // Serializes the system metrics to value.
588   Value::Dict ToDict() const;
589 
590  private:
591   FRIEND_TEST_ALL_PREFIXES(SystemMetricsTest, SystemMetrics);
592 
593   size_t committed_memory_;
594 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
595   SystemMemoryInfoKB memory_info_;
596   VmStatInfo vmstat_info_;
597   SystemDiskInfo disk_info_;
598 #endif
599 #if BUILDFLAG(IS_CHROMEOS)
600   SwapInfo swap_info_;
601   GraphicsMemoryInfoKB gpu_memory_info_;
602 #endif
603 #if BUILDFLAG(IS_WIN)
604   SystemPerformanceInfo performance_;
605 #endif
606 };
607 
608 #if BUILDFLAG(IS_APPLE)
609 enum class MachVMRegionResult {
610   // There were no more memory regions between |address| and the end of the
611   // virtual address space.
612   Finished,
613 
614   // All output parameters are invalid.
615   Error,
616 
617   // All output parameters are filled in.
618   Success
619 };
620 
621 // Returns info on the first memory region at or after |address|, including
622 // protection values. On Success, |size| reflects the size of the
623 // memory region.
624 // Returns info on the first memory region at or after |address|, including
625 // resident memory and share mode.
626 // |size| and |info| are output parameters, only valid on Success.
627 BASE_EXPORT MachVMRegionResult GetBasicInfo(mach_port_t task,
628                                             mach_vm_size_t* size,
629                                             mach_vm_address_t* address,
630                                             vm_region_basic_info_64* info);
631 #endif  // BUILDFLAG(IS_APPLE)
632 
633 #if BUILDFLAG(IS_MAC)
634 // Returns info on the first memory region at or after |address|, including
635 // resident memory and share mode. On Success, |size| reflects the size of the
636 // memory region.
637 // |size| and |info| are output parameters, only valid on Success.
638 // |address| is an in-out parameter, than represents both the address to start
639 // looking, and the start address of the memory region.
640 BASE_EXPORT MachVMRegionResult GetTopInfo(mach_port_t task,
641                                           mach_vm_size_t* size,
642                                           mach_vm_address_t* address,
643                                           vm_region_top_info_data_t* info);
644 #endif  // BUILDFLAG(IS_MAC)
645 
646 }  // namespace base
647 
648 #endif  // BASE_PROCESS_PROCESS_METRICS_H_
649