[go: nahoru, domu]

blob: 50a5626d36cb176080d08f7be705382d9a868dc0 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// 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.commitd7cae122008-07-26 21:49:384
5// This file/namespace contains utility functions for enumerating, ending and
6// computing statistics of processes.
7
deanm@google.comdb717282008-08-27 13:48:038#ifndef BASE_PROCESS_UTIL_H_
9#define BASE_PROCESS_UTIL_H_
initial.commitd7cae122008-07-26 21:49:3810
paulg@google.com61659062008-08-06 01:04:1811#include "base/basictypes.h"
12
dkegel@google.comab0e2222008-10-31 20:19:4313#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:3814#include <windows.h>
15#include <tlhelp32.h>
dkegel@google.comab0e2222008-10-31 20:19:4316#elif defined(OS_LINUX)
17#include <dirent.h>
18#include <limits.h>
19#include <sys/types.h>
paulg@google.com61659062008-08-06 01:04:1820#endif
initial.commitd7cae122008-07-26 21:49:3821
paulg@google.com61659062008-08-06 01:04:1822#include <string>
23
estade@chromium.orgfb7f9be2008-10-22 01:15:4724#include "base/command_line.h"
initial.commitd7cae122008-07-26 21:49:3825#include "base/process.h"
26
paulg@google.com61659062008-08-06 01:04:1827#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:3828typedef PROCESSENTRY32 ProcessEntry;
29typedef IO_COUNTERS IoCounters;
paulg@google.com61659062008-08-06 01:04:1830#elif defined(OS_POSIX)
dkegel@google.comab0e2222008-10-31 20:19:4331struct ProcessEntry {
32 int pid;
33 int ppid;
34 char szExeFile[NAME_MAX+1];
35};
36
evanm@google.com0b100bc82008-10-14 20:49:1637struct IoCounters {
38 unsigned long long ReadOperationCount;
39 unsigned long long WriteOperationCount;
40 unsigned long long OtherOperationCount;
41 unsigned long long ReadTransferCount;
42 unsigned long long WriteTransferCount;
43 unsigned long long OtherTransferCount;
44};
initial.commitd7cae122008-07-26 21:49:3845#endif
46
47namespace process_util {
48
49// Returns the id of the current process.
50int GetCurrentProcId();
51
erikkay@google.com113ab132008-09-18 20:42:5552// Returns the ProcessHandle of the current process.
53ProcessHandle GetCurrentProcessHandle();
54
initial.commitd7cae122008-07-26 21:49:3855// Returns the unique ID for the specified process. This is functionally the
56// same as Windows' GetProcessId(), but works on versions of Windows before
57// Win XP SP1 as well.
58int GetProcId(ProcessHandle process);
59
estade@chromium.orgfb7f9be2008-10-22 01:15:4760#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:3861// Runs the given application name with the given command line. Normally, the
62// first command line argument should be the path to the process, and don't
63// forget to quote it.
64//
65// If wait is true, it will block and wait for the other process to finish,
66// otherwise, it will just continue asynchronously.
67//
68// Example (including literal quotes)
69// cmdline = "c:\windows\explorer.exe" -foo "c:\bar\"
70//
71// If process_handle is non-NULL, the process handle of the launched app will be
72// stored there on a successful launch.
73// NOTE: In this case, the caller is responsible for closing the handle so
74// that it doesn't leak!
75bool LaunchApp(const std::wstring& cmdline,
estade@chromium.orgfb7f9be2008-10-22 01:15:4776 bool wait, bool start_hidden, ProcessHandle* process_handle);
77#elif defined(OS_POSIX)
78// Runs the application specified in argv[0] with the command line argv.
79// Both the elements of argv and argv itself must be terminated with a null
80// byte.
81//
82// As above, if wait is true, execute synchronously. The pid will be stored
83// in process_handle if that pointer is non-null.
84//
85// Note that the first argument in argv must point to the filename,
86// and must be fully specified.
87bool LaunchApp(const std::vector<std::string>& argv,
88 bool wait, ProcessHandle* process_handle);
89#endif
90
91// Execute the application specified by cl. This function delegates to one
92// of the above two platform-specific functions.
93bool LaunchApp(const CommandLine& cl,
initial.commitd7cae122008-07-26 21:49:3894 bool wait, bool start_hidden, ProcessHandle* process_handle);
95
96// Used to filter processes by process ID.
97class ProcessFilter {
98 public:
99 // Returns true to indicate set-inclusion and false otherwise. This method
100 // should not have side-effects and should be idempotent.
101 virtual bool Includes(uint32 pid, uint32 parent_pid) const = 0;
avi@google.comdd950aa2008-08-12 21:24:39102 virtual ~ProcessFilter() { }
initial.commitd7cae122008-07-26 21:49:38103};
104
105// Returns the number of processes on the machine that are running from the
106// given executable name. If filter is non-null, then only processes selected
107// by the filter will be counted.
108int GetProcessCount(const std::wstring& executable_name,
109 const ProcessFilter* filter);
110
111// Attempts to kill all the processes on the current machine that were launched
112// from the given executable name, ending them with the given exit code. If
113// filter is non-null, then only processes selected by the filter are killed.
114// Returns false if all processes were able to be killed off, false if at least
115// one couldn't be killed.
116bool KillProcesses(const std::wstring& executable_name, int exit_code,
117 const ProcessFilter* filter);
118
119// Attempts to kill the process identified by the given process
120// entry structure, giving it the specified exit code. If |wait| is true, wait
121// for the process to be actually terminated before returning.
122// Returns true if this is successful, false otherwise.
123bool KillProcess(int process_id, int exit_code, bool wait);
124
125// Get the termination status (exit code) of the process and return true if the
126// status indicates the process crashed. It is an error to call this if the
127// process hasn't terminated yet.
128bool DidProcessCrash(ProcessHandle handle);
129
130// Wait for all the processes based on the named executable to exit. If filter
131// is non-null, then only processes selected by the filter are waited on.
132// Returns after all processes have exited or wait_milliseconds have expired.
133// Returns true if all the processes exited, false otherwise.
134bool WaitForProcessesToExit(const std::wstring& executable_name,
135 int wait_milliseconds,
136 const ProcessFilter* filter);
137
estade@chromium.orgfb7f9be2008-10-22 01:15:47138// Wait for a single process to exit. Return true if it exited cleanly within
139// the given time limit.
140bool WaitForSingleProcess(ProcessHandle handle,
141 int wait_milliseconds);
142
initial.commitd7cae122008-07-26 21:49:38143// Waits a certain amount of time (can be 0) for all the processes with a given
144// executable name to exit, then kills off any of them that are still around.
145// If filter is non-null, then only processes selected by the filter are waited
146// on. Killed processes are ended with the given exit code. Returns false if
147// any processes needed to be killed, true if they all exited cleanly within
148// the wait_milliseconds delay.
149bool CleanupProcesses(const std::wstring& executable_name,
150 int wait_milliseconds,
151 int exit_code,
152 const ProcessFilter* filter);
153
154// This class provides a way to iterate through the list of processes
155// on the current machine that were started from the given executable
156// name. To use, create an instance and then call NextProcessEntry()
157// until it returns false.
158class NamedProcessIterator {
159 public:
160 NamedProcessIterator(const std::wstring& executable_name,
161 const ProcessFilter* filter);
162 ~NamedProcessIterator();
163
164 // If there's another process that matches the given executable name,
165 // returns a const pointer to the corresponding PROCESSENTRY32.
166 // If there are no more matching processes, returns NULL.
167 // The returned pointer will remain valid until NextProcessEntry()
168 // is called again or this NamedProcessIterator goes out of scope.
169 const ProcessEntry* NextProcessEntry();
170
171 private:
172 // Determines whether there's another process (regardless of executable)
173 // left in the list of all processes. Returns true and sets entry_ to
174 // that process's info if there is one, false otherwise.
175 bool CheckForNextProcess();
176
177 bool IncludeEntry();
178
179 // Initializes a PROCESSENTRY32 data structure so that it's ready for
180 // use with Process32First/Process32Next.
181 void InitProcessEntry(ProcessEntry* entry);
182
183 std::wstring executable_name_;
dkegel@google.comab0e2222008-10-31 20:19:43184
185#if defined(OS_WIN)
initial.commitd7cae122008-07-26 21:49:38186 HANDLE snapshot_;
initial.commitd7cae122008-07-26 21:49:38187 bool started_iteration_;
dkegel@google.comab0e2222008-10-31 20:19:43188#elif defined(OS_LINUX)
189 DIR *procfs_dir_;
190#elif defined(OS_MACOSX)
191 // probably kvm_t *kvmd_;
192#endif
193
initial.commitd7cae122008-07-26 21:49:38194 ProcessEntry entry_;
195 const ProcessFilter* filter_;
196
197 DISALLOW_EVIL_CONSTRUCTORS(NamedProcessIterator);
198};
199
200// Working Set (resident) memory usage broken down by
201// priv (private): These pages (kbytes) cannot be shared with any other process.
202// shareable: These pages (kbytes) can be shared with other processes under
203// the right circumstances.
204// shared : These pages (kbytes) are currently shared with at least one
205// other process.
206struct WorkingSetKBytes {
207 size_t priv;
208 size_t shareable;
209 size_t shared;
210};
211
212// Committed (resident + paged) memory usage broken down by
213// private: These pages cannot be shared with any other process.
214// mapped: These pages are mapped into the view of a section (backed by
215// pagefile.sys)
216// image: These pages are mapped into the view of an image section (backed by
217// file system)
218struct CommittedKBytes {
219 size_t priv;
220 size_t mapped;
221 size_t image;
222};
223
224// Free memory (Megabytes marked as free) in the 2G process address space.
225// total : total amount in megabytes marked as free. Maximum value is 2048.
226// largest : size of the largest contiguous amount of memory found. It is
227// always smaller or equal to FreeMBytes::total.
228// largest_ptr: starting address of the largest memory block.
229struct FreeMBytes {
230 size_t total;
231 size_t largest;
232 void* largest_ptr;
233};
234
235// Provides performance metrics for a specified process (CPU usage, memory and
236// IO counters). To use it, invoke CreateProcessMetrics() to get an instance
237// for a specific process, then access the information with the different get
238// methods.
239class ProcessMetrics {
240 public:
241 // Creates a ProcessMetrics for the specified process.
242 // The caller owns the returned object.
243 static ProcessMetrics* CreateProcessMetrics(ProcessHandle process);
244
245 ~ProcessMetrics();
246
247 // Returns the current space allocated for the pagefile, in bytes (these pages
248 // may or may not be in memory).
249 size_t GetPagefileUsage();
250 // Returns the peak space allocated for the pagefile, in bytes.
251 size_t GetPeakPagefileUsage();
252 // Returns the current working set size, in bytes.
253 size_t GetWorkingSetSize();
254 // Returns private usage, in bytes. Private bytes is the amount
255 // of memory currently allocated to a process that cannot be shared.
256 // Note: returns 0 on unsupported OSes: prior to XP SP2.
257 size_t GetPrivateBytes();
258 // Fills a CommittedKBytes with both resident and paged
259 // memory usage as per definition of CommittedBytes.
260 void GetCommittedKBytes(CommittedKBytes* usage);
261 // Fills a WorkingSetKBytes containing resident private and shared memory
262 // usage in bytes, as per definition of WorkingSetBytes.
263 bool GetWorkingSetKBytes(WorkingSetKBytes* ws_usage);
264
265 // Computes the current process available memory for allocation.
266 // It does a linear scan of the address space querying each memory region
267 // for its free (unallocated) status. It is useful for estimating the memory
268 // load and fragmentation.
269 bool CalculateFreeMemory(FreeMBytes* free);
270
271 // Returns the CPU usage in percent since the last time this method was
272 // called. The first time this method is called it returns 0 and will return
273 // the actual CPU info on subsequent calls.
274 // Note that on multi-processor machines, the CPU usage value is for all
275 // CPUs. So if you have 2 CPUs and your process is using all the cycles
276 // of 1 CPU and not the other CPU, this method returns 50.
277 int GetCPUUsage();
278
279 // Retrieves accounting information for all I/O operations performed by the
280 // process.
281 // If IO information is retrieved successfully, the function returns true
282 // and fills in the IO_COUNTERS passed in. The function returns false
283 // otherwise.
284 bool GetIOCounters(IoCounters* io_counters);
285
286 private:
287 explicit ProcessMetrics(ProcessHandle process);
288
289 ProcessHandle process_;
290
291 int processor_count_;
292
293 // Used to store the previous times so we can compute the CPU usage.
294 int64 last_time_;
295 int64 last_system_time_;
296
297 DISALLOW_EVIL_CONSTRUCTORS(ProcessMetrics);
298};
299
300// Enables low fragmentation heap (LFH) for every heaps of this process. This
301// won't have any effect on heaps created after this function call. It will not
302// modify data allocated in the heaps before calling this function. So it is
303// better to call this function early in initialization and again before
304// entering the main loop.
305// Note: Returns true on Windows 2000 without doing anything.
306bool EnableLowFragmentationHeap();
307
maruel@google.comc9d40872008-09-24 12:58:37308// Enable 'terminate on heap corruption' flag. Helps protect against heap
309// overflow. Has no effect if the OS doesn't provide the necessary facility.
310void EnableTerminationOnHeapCorruption();
311
deanm@google.comdb717282008-08-27 13:48:03312// If supported on the platform, and the user has sufficent rights, increase
313// the current process's scheduling priority to a high priority.
314void RaiseProcessToHighPriority();
315
initial.commitd7cae122008-07-26 21:49:38316} // namespace process_util
317
deanm@google.comdb717282008-08-27 13:48:03318#endif // BASE_PROCESS_UTIL_H_