process_metrics.h revision 58537e28ecd584eab876aee8be7156509866d23a
1// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// 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 <string> 12 13#include "base/base_export.h" 14#include "base/basictypes.h" 15#include "base/gtest_prod_util.h" 16#include "base/process/process_handle.h" 17#include "base/time/time.h" 18#include "base/values.h" 19 20#if defined(OS_MACOSX) 21#include <mach/mach.h> 22#endif 23 24namespace base { 25 26#if defined(OS_WIN) 27struct IoCounters : public IO_COUNTERS { 28}; 29#elif defined(OS_POSIX) 30struct IoCounters { 31 uint64_t ReadOperationCount; 32 uint64_t WriteOperationCount; 33 uint64_t OtherOperationCount; 34 uint64_t ReadTransferCount; 35 uint64_t WriteTransferCount; 36 uint64_t OtherTransferCount; 37}; 38#endif 39 40// Working Set (resident) memory usage broken down by 41// 42// On Windows: 43// priv (private): These pages (kbytes) cannot be shared with any other process. 44// shareable: These pages (kbytes) can be shared with other processes under 45// the right circumstances. 46// shared : These pages (kbytes) are currently shared with at least one 47// other process. 48// 49// On Linux: 50// priv: Pages mapped only by this process. 51// shared: PSS or 0 if the kernel doesn't support this. 52// shareable: 0 53 54// On ChromeOS: 55// priv: Pages mapped only by this process. 56// shared: PSS or 0 if the kernel doesn't support this. 57// shareable: 0 58// swapped Pages swapped out to zram. 59// 60// On OS X: TODO(thakis): Revise. 61// priv: Memory. 62// shared: 0 63// shareable: 0 64// 65struct WorkingSetKBytes { 66 WorkingSetKBytes() : priv(0), shareable(0), shared(0) {} 67 size_t priv; 68 size_t shareable; 69 size_t shared; 70#if defined(OS_CHROMEOS) 71 size_t swapped; 72#endif 73}; 74 75// Committed (resident + paged) memory usage broken down by 76// private: These pages cannot be shared with any other process. 77// mapped: These pages are mapped into the view of a section (backed by 78// pagefile.sys) 79// image: These pages are mapped into the view of an image section (backed by 80// file system) 81struct CommittedKBytes { 82 CommittedKBytes() : priv(0), mapped(0), image(0) {} 83 size_t priv; 84 size_t mapped; 85 size_t image; 86}; 87 88// Free memory (Megabytes marked as free) in the 2G process address space. 89// total : total amount in megabytes marked as free. Maximum value is 2048. 90// largest : size of the largest contiguous amount of memory found. It is 91// always smaller or equal to FreeMBytes::total. 92// largest_ptr: starting address of the largest memory block. 93struct FreeMBytes { 94 size_t total; 95 size_t largest; 96 void* largest_ptr; 97}; 98 99// Convert a POSIX timeval to microseconds. 100BASE_EXPORT int64 TimeValToMicroseconds(const struct timeval& tv); 101 102// Provides performance metrics for a specified process (CPU usage, memory and 103// IO counters). To use it, invoke CreateProcessMetrics() to get an instance 104// for a specific process, then access the information with the different get 105// methods. 106class BASE_EXPORT ProcessMetrics { 107 public: 108 ~ProcessMetrics(); 109 110 // Creates a ProcessMetrics for the specified process. 111 // The caller owns the returned object. 112#if !defined(OS_MACOSX) || defined(OS_IOS) 113 static ProcessMetrics* CreateProcessMetrics(ProcessHandle process); 114#else 115 class PortProvider { 116 public: 117 virtual ~PortProvider() {} 118 119 // Should return the mach task for |process| if possible, or else 120 // |MACH_PORT_NULL|. Only processes that this returns tasks for will have 121 // metrics on OS X (except for the current process, which always gets 122 // metrics). 123 virtual mach_port_t TaskForPid(ProcessHandle process) const = 0; 124 }; 125 126 // The port provider needs to outlive the ProcessMetrics object returned by 127 // this function. If NULL is passed as provider, the returned object 128 // only returns valid metrics if |process| is the current process. 129 static ProcessMetrics* CreateProcessMetrics(ProcessHandle process, 130 PortProvider* port_provider); 131#endif // !defined(OS_MACOSX) || defined(OS_IOS) 132 133 // Returns the current space allocated for the pagefile, in bytes (these pages 134 // may or may not be in memory). On Linux, this returns the total virtual 135 // memory size. 136 size_t GetPagefileUsage() const; 137 // Returns the peak space allocated for the pagefile, in bytes. 138 size_t GetPeakPagefileUsage() const; 139 // Returns the current working set size, in bytes. On Linux, this returns 140 // the resident set size. 141 size_t GetWorkingSetSize() const; 142 // Returns the peak working set size, in bytes. 143 size_t GetPeakWorkingSetSize() const; 144 // Returns private and sharedusage, in bytes. Private bytes is the amount of 145 // memory currently allocated to a process that cannot be shared. Returns 146 // false on platform specific error conditions. Note: |private_bytes| 147 // returns 0 on unsupported OSes: prior to XP SP2. 148 bool GetMemoryBytes(size_t* private_bytes, 149 size_t* shared_bytes); 150 // Fills a CommittedKBytes with both resident and paged 151 // memory usage as per definition of CommittedBytes. 152 void GetCommittedKBytes(CommittedKBytes* usage) const; 153 // Fills a WorkingSetKBytes containing resident private and shared memory 154 // usage in bytes, as per definition of WorkingSetBytes. 155 bool GetWorkingSetKBytes(WorkingSetKBytes* ws_usage) const; 156 157 // Computes the current process available memory for allocation. 158 // It does a linear scan of the address space querying each memory region 159 // for its free (unallocated) status. It is useful for estimating the memory 160 // load and fragmentation. 161 bool CalculateFreeMemory(FreeMBytes* free) const; 162 163 // Returns the CPU usage in percent since the last time this method was 164 // called. The first time this method is called it returns 0 and will return 165 // the actual CPU info on subsequent calls. 166 // On Windows, the CPU usage value is for all CPUs. So if you have 2 CPUs and 167 // your process is using all the cycles of 1 CPU and not the other CPU, this 168 // method returns 50. 169 double GetCPUUsage(); 170 171 // Retrieves accounting information for all I/O operations performed by the 172 // process. 173 // If IO information is retrieved successfully, the function returns true 174 // and fills in the IO_COUNTERS passed in. The function returns false 175 // otherwise. 176 bool GetIOCounters(IoCounters* io_counters) const; 177 178 private: 179#if !defined(OS_MACOSX) || defined(OS_IOS) 180 explicit ProcessMetrics(ProcessHandle process); 181#else 182 ProcessMetrics(ProcessHandle process, PortProvider* port_provider); 183#endif // !defined(OS_MACOSX) || defined(OS_IOS) 184 185#if defined(OS_LINUX) || defined(OS_ANDROID) 186 bool GetWorkingSetKBytesStatm(WorkingSetKBytes* ws_usage) const; 187#endif 188 189#if defined(OS_CHROMEOS) 190 bool GetWorkingSetKBytesTotmaps(WorkingSetKBytes *ws_usage) const; 191#endif 192 193 ProcessHandle process_; 194 195 int processor_count_; 196 197 // Used to store the previous times and CPU usage counts so we can 198 // compute the CPU usage between calls. 199 int64 last_time_; 200 int64 last_system_time_; 201 202#if !defined(OS_IOS) 203#if defined(OS_MACOSX) 204 // Queries the port provider if it's set. 205 mach_port_t TaskForPid(ProcessHandle process) const; 206 207 PortProvider* port_provider_; 208#elif defined(OS_POSIX) 209 // Jiffie count at the last_time_ we updated. 210 int last_cpu_; 211#endif // defined(OS_POSIX) 212#endif // !defined(OS_IOS) 213 214 DISALLOW_COPY_AND_ASSIGN(ProcessMetrics); 215}; 216 217// Returns the memory committed by the system in KBytes. 218// Returns 0 if it can't compute the commit charge. 219BASE_EXPORT size_t GetSystemCommitCharge(); 220 221#if defined(OS_POSIX) 222// Returns the maximum number of file descriptors that can be open by a process 223// at once. If the number is unavailable, a conservative best guess is returned. 224size_t GetMaxFds(); 225#endif // defined(OS_POSIX) 226 227#if defined(OS_LINUX) || defined(OS_ANDROID) 228// Parse the data found in /proc/<pid>/stat and return the sum of the 229// CPU-related ticks. Returns -1 on parse error. 230// Exposed for testing. 231BASE_EXPORT int ParseProcStatCPU(const std::string& input); 232 233// Get the number of threads of |process| as available in /proc/<pid>/stat. 234// This should be used with care as no synchronization with running threads is 235// done. This is mostly useful to guarantee being single-threaded. 236// Returns 0 on failure. 237BASE_EXPORT int GetNumberOfThreads(ProcessHandle process); 238 239// /proc/self/exe refers to the current executable. 240BASE_EXPORT extern const char kProcSelfExe[]; 241 242// Data from /proc/meminfo about system-wide memory consumption. 243// Values are in KB. 244struct BASE_EXPORT SystemMemoryInfoKB { 245 SystemMemoryInfoKB(); 246 247 // Serializes the platform specific fields to value. 248 scoped_ptr<Value> ToValue() const; 249 250 int total; 251 int free; 252 int buffers; 253 int cached; 254 int active_anon; 255 int inactive_anon; 256 int active_file; 257 int inactive_file; 258 int swap_total; 259 int swap_free; 260 int dirty; 261 262 // vmstats data. 263 int pswpin; 264 int pswpout; 265 int pgmajfault; 266 267#ifdef OS_CHROMEOS 268 int shmem; 269 int slab; 270 // Gem data will be -1 if not supported. 271 int gem_objects; 272 long long gem_size; 273#endif 274}; 275 276// Retrieves data from /proc/meminfo and /proc/vmstat 277// about system-wide memory consumption. 278// Fills in the provided |meminfo| structure. Returns true on success. 279// Exposed for memory debugging widget. 280BASE_EXPORT bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo); 281 282// Data from /proc/diskstats about system-wide disk I/O. 283struct BASE_EXPORT SystemDiskInfo { 284 SystemDiskInfo(); 285 286 // Serializes the platform specific fields to value. 287 scoped_ptr<Value> ToValue() const; 288 289 uint64 reads; 290 uint64 reads_merged; 291 uint64 sectors_read; 292 uint64 read_time; 293 uint64 writes; 294 uint64 writes_merged; 295 uint64 sectors_written; 296 uint64 write_time; 297 uint64 io; 298 uint64 io_time; 299 uint64 weighted_io_time; 300}; 301 302// Checks whether the candidate string is a valid disk name, [sh]d[a-z]+ 303// for a generic disk or mmcblk[0-9]+ for the MMC case. 304// Names of disk partitions (e.g. sda1) are not valid. 305BASE_EXPORT bool IsValidDiskName(const std::string& candidate); 306 307// Retrieves data from /proc/diskstats about system-wide disk I/O. 308// Fills in the provided |diskinfo| structure. Returns true on success. 309BASE_EXPORT bool GetSystemDiskInfo(SystemDiskInfo* diskinfo); 310#endif // defined(OS_LINUX) || defined(OS_ANDROID) 311 312#if defined(OS_CHROMEOS) 313// Data from files in directory /sys/block/zram0 about ZRAM usage. 314struct BASE_EXPORT SwapInfo { 315 SwapInfo() 316 : num_reads(0), 317 num_writes(0), 318 compr_data_size(0), 319 orig_data_size(0), 320 mem_used_total(0) { 321 } 322 323 // Serializes the platform specific fields to value. 324 scoped_ptr<Value> ToValue() const; 325 326 uint64 num_reads; 327 uint64 num_writes; 328 uint64 compr_data_size; 329 uint64 orig_data_size; 330 uint64 mem_used_total; 331}; 332 333// In ChromeOS, reads files from /sys/block/zram0 that contain ZRAM usage data. 334// Fills in the provided |swap_data| structure. 335BASE_EXPORT void GetSwapInfo(SwapInfo* swap_info); 336#endif // defined(OS_CHROMEOS) 337 338// Collects and holds performance metrics for system memory and disk. 339// Provides functionality to retrieve the data on various platforms and 340// to serialize the stored data. 341class SystemMetrics { 342 public: 343 SystemMetrics(); 344 345 static SystemMetrics Sample(); 346 347 // Serializes the system metrics to value. 348 scoped_ptr<Value> ToValue() const; 349 350 private: 351 FRIEND_TEST_ALL_PREFIXES(SystemMetricsTest, SystemMetrics); 352 353 size_t committed_memory_; 354#if defined(OS_LINUX) || defined(OS_ANDROID) 355 SystemMemoryInfoKB memory_info_; 356 SystemDiskInfo disk_info_; 357#endif 358#if defined(OS_CHROMEOS) 359 SwapInfo swap_info_; 360#endif 361}; 362 363} // namespace base 364 365#endif // BASE_PROCESS_PROCESS_METRICS_H_ 366