blob: 978da42c2b1e3081c0ee878441552d7891d17613 [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// Copyright (c) 2006-2008 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.
initial.commit3f4a7322008-07-27 06:49:38 +09004
5// This file/namespace contains utility functions for enumerating, ending and
6// computing statistics of processes.
7
8#ifndef BASE_PROCESS_UTIL_H__
9#define BASE_PROCESS_UTIL_H__
10
paulg@google.comd76d17d2008-08-06 10:04:18 +090011#include "base/basictypes.h"
12
13#ifdef OS_WIN
initial.commit3f4a7322008-07-27 06:49:38 +090014#include <windows.h>
15#include <tlhelp32.h>
paulg@google.comd76d17d2008-08-06 10:04:18 +090016#endif
initial.commit3f4a7322008-07-27 06:49:38 +090017
paulg@google.comd76d17d2008-08-06 10:04:18 +090018#include <string>
19
initial.commit3f4a7322008-07-27 06:49:38 +090020#include "base/process.h"
21
22// ProcessHandle is a platform specific type which represents the underlying OS
23// handle to a process.
paulg@google.comd76d17d2008-08-06 10:04:18 +090024#if defined(OS_WIN)
initial.commit3f4a7322008-07-27 06:49:38 +090025typedef PROCESSENTRY32 ProcessEntry;
26typedef IO_COUNTERS IoCounters;
paulg@google.comd76d17d2008-08-06 10:04:18 +090027#elif defined(OS_POSIX)
initial.commit3f4a7322008-07-27 06:49:38 +090028typedef int ProcessEntry;
paulg@google.comd76d17d2008-08-06 10:04:18 +090029typedef int IoCounters; //TODO(awalker): replace with struct when available
initial.commit3f4a7322008-07-27 06:49:38 +090030#endif
31
32namespace process_util {
33
34// Returns the id of the current process.
35int GetCurrentProcId();
36
37// Returns the unique ID for the specified process. This is functionally the
38// same as Windows' GetProcessId(), but works on versions of Windows before
39// Win XP SP1 as well.
40int GetProcId(ProcessHandle process);
41
42// Runs the given application name with the given command line. Normally, the
43// first command line argument should be the path to the process, and don't
44// forget to quote it.
45//
46// If wait is true, it will block and wait for the other process to finish,
47// otherwise, it will just continue asynchronously.
48//
49// Example (including literal quotes)
50// cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
51//
52// If process_handle is non-NULL, the process handle of the launched app will be
53// stored there on a successful launch.
54// NOTE: In this case, the caller is responsible for closing the handle so
55// that it doesn't leak!
56bool LaunchApp(const std::wstring& cmdline,
57 bool wait, bool start_hidden, ProcessHandle* process_handle);
58
59// Used to filter processes by process ID.
60class ProcessFilter {
61 public:
62 // Returns true to indicate set-inclusion and false otherwise. This method
63 // should not have side-effects and should be idempotent.
64 virtual bool Includes(uint32 pid, uint32 parent_pid) const = 0;
avi@google.com0890c5a2008-08-13 06:24:39 +090065 virtual ~ProcessFilter() { }
initial.commit3f4a7322008-07-27 06:49:38 +090066};
67
68// Returns the number of processes on the machine that are running from the
69// given executable name. If filter is non-null, then only processes selected
70// by the filter will be counted.
71int GetProcessCount(const std::wstring& executable_name,
72 const ProcessFilter* filter);
73
74// Attempts to kill all the processes on the current machine that were launched
75// from the given executable name, ending them with the given exit code. If
76// filter is non-null, then only processes selected by the filter are killed.
77// Returns false if all processes were able to be killed off, false if at least
78// one couldn't be killed.
79bool KillProcesses(const std::wstring& executable_name, int exit_code,
80 const ProcessFilter* filter);
81
82// Attempts to kill the process identified by the given process
83// entry structure, giving it the specified exit code. If |wait| is true, wait
84// for the process to be actually terminated before returning.
85// Returns true if this is successful, false otherwise.
86bool KillProcess(int process_id, int exit_code, bool wait);
87
88// Get the termination status (exit code) of the process and return true if the
89// status indicates the process crashed. It is an error to call this if the
90// process hasn't terminated yet.
91bool DidProcessCrash(ProcessHandle handle);
92
93// Wait for all the processes based on the named executable to exit. If filter
94// is non-null, then only processes selected by the filter are waited on.
95// Returns after all processes have exited or wait_milliseconds have expired.
96// Returns true if all the processes exited, false otherwise.
97bool WaitForProcessesToExit(const std::wstring& executable_name,
98 int wait_milliseconds,
99 const ProcessFilter* filter);
100
101// Waits a certain amount of time (can be 0) for all the processes with a given
102// executable name to exit, then kills off any of them that are still around.
103// If filter is non-null, then only processes selected by the filter are waited
104// on. Killed processes are ended with the given exit code. Returns false if
105// any processes needed to be killed, true if they all exited cleanly within
106// the wait_milliseconds delay.
107bool CleanupProcesses(const std::wstring& executable_name,
108 int wait_milliseconds,
109 int exit_code,
110 const ProcessFilter* filter);
111
112// This class provides a way to iterate through the list of processes
113// on the current machine that were started from the given executable
114// name. To use, create an instance and then call NextProcessEntry()
115// until it returns false.
116class NamedProcessIterator {
117 public:
118 NamedProcessIterator(const std::wstring& executable_name,
119 const ProcessFilter* filter);
120 ~NamedProcessIterator();
121
122 // If there's another process that matches the given executable name,
123 // returns a const pointer to the corresponding PROCESSENTRY32.
124 // If there are no more matching processes, returns NULL.
125 // The returned pointer will remain valid until NextProcessEntry()
126 // is called again or this NamedProcessIterator goes out of scope.
127 const ProcessEntry* NextProcessEntry();
128
129 private:
130 // Determines whether there's another process (regardless of executable)
131 // left in the list of all processes. Returns true and sets entry_ to
132 // that process's info if there is one, false otherwise.
133 bool CheckForNextProcess();
134
135 bool IncludeEntry();
136
137 // Initializes a PROCESSENTRY32 data structure so that it's ready for
138 // use with Process32First/Process32Next.
139 void InitProcessEntry(ProcessEntry* entry);
140
141 std::wstring executable_name_;
paulg@google.comd76d17d2008-08-06 10:04:18 +0900142#ifdef OS_WIN
initial.commit3f4a7322008-07-27 06:49:38 +0900143 HANDLE snapshot_;
paulg@google.comd76d17d2008-08-06 10:04:18 +0900144#endif
initial.commit3f4a7322008-07-27 06:49:38 +0900145 bool started_iteration_;
146 ProcessEntry entry_;
147 const ProcessFilter* filter_;
148
149 DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator);
150};
151
152// Working Set (resident) memory usage broken down by
153// priv (private): These pages (kbytes) cannot be shared with any other process.
154// shareable: These pages (kbytes) can be shared with other processes under
155// the right circumstances.
156// shared : These pages (kbytes) are currently shared with at least one
157// other process.
158struct WorkingSetKBytes {
159 size_t priv;
160 size_t shareable;
161 size_t shared;
162};
163
164// Committed (resident + paged) memory usage broken down by
165// private: These pages cannot be shared with any other process.
166// mapped: These pages are mapped into the view of a section (backed by
167// pagefile.sys)
168// image: These pages are mapped into the view of an image section (backed by
169// file system)
170struct CommittedKBytes {
171 size_t priv;
172 size_t mapped;
173 size_t image;
174};
175
176// Free memory (Megabytes marked as free) in the 2G process address space.
177// total : total amount in megabytes marked as free. Maximum value is 2048.
178// largest : size of the largest contiguous amount of memory found. It is
179// always smaller or equal to FreeMBytes::total.
180// largest_ptr: starting address of the largest memory block.
181struct FreeMBytes {
182 size_t total;
183 size_t largest;
184 void* largest_ptr;
185};
186
187// Provides performance metrics for a specified process (CPU usage, memory and
188// IO counters). To use it, invoke CreateProcessMetrics() to get an instance
189// for a specific process, then access the information with the different get
190// methods.
191class ProcessMetrics {
192 public:
193 // Creates a ProcessMetrics for the specified process.
194 // The caller owns the returned object.
195 static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
196
197 ~ProcessMetrics();
198
199 // Returns the current space allocated for the pagefile, in bytes (these pages
200 // may or may not be in memory).
201 size_t GetPagefileUsage();
202 // Returns the peak space allocated for the pagefile, in bytes.
203 size_t GetPeakPagefileUsage();
204 // Returns the current working set size, in bytes.
205 size_t GetWorkingSetSize();
206 // Returns private usage, in bytes. Private bytes is the amount
207 // of memory currently allocated to a process that cannot be shared.
208 // Note: returns 0 on unsupported OSes: prior to XP SP2.
209 size_t GetPrivateBytes();
210 // Fills a CommittedKBytes with both resident and paged
211 // memory usage as per definition of CommittedBytes.
212 void GetCommittedKBytes(CommittedKBytes* usage);
213 // Fills a WorkingSetKBytes containing resident private and shared memory
214 // usage in bytes, as per definition of WorkingSetBytes.
215 bool GetWorkingSetKBytes(WorkingSetKBytes* ws_usage);
216
217 // Computes the current process available memory for allocation.
218 // It does a linear scan of the address space querying each memory region
219 // for its free (unallocated) status. It is useful for estimating the memory
220 // load and fragmentation.
221 bool CalculateFreeMemory(FreeMBytes* free);
222
223 // Returns the CPU usage in percent since the last time this method was
224 // called. The first time this method is called it returns 0 and will return
225 // the actual CPU info on subsequent calls.
226 // Note that on multi-processor machines, the CPU usage value is for all
227 // CPUs. So if you have 2 CPUs and your process is using all the cycles
228 // of 1 CPU and not the other CPU, this method returns 50.
229 int GetCPUUsage();
230
231 // Retrieves accounting information for all I/O operations performed by the
232 // process.
233 // If IO information is retrieved successfully, the function returns true
234 // and fills in the IO_COUNTERS passed in. The function returns false
235 // otherwise.
236 bool GetIOCounters(IoCounters* io_counters);
237
238 private:
239 explicit ProcessMetrics(ProcessHandle process);
240
241 ProcessHandle process_;
242
243 int processor_count_;
244
245 // Used to store the previous times so we can compute the CPU usage.
246 int64 last_time_;
247 int64 last_system_time_;
248
249 DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics);
250};
251
252// Enables low fragmentation heap (LFH) for every heaps of this process. This
253// won't have any effect on heaps created after this function call. It will not
254// modify data allocated in the heaps before calling this function. So it is
255// better to call this function early in initialization and again before
256// entering the main loop.
257// Note: Returns true on Windows 2000 without doing anything.
258bool EnableLowFragmentationHeap();
259
260} // namespace process_util
261
262
263#endif // BASE_PROCESS_UTIL_H__
license.botf003cfe2008-08-24 09:55:55 +0900264