Bug 1933479 - Add tab close button on hover to vertical tabs when sidebar is collapse...
[gecko.git] / toolkit / components / processtools / ProcInfo.h
blob8a118da710d221e866c38432a5184e7e69863b25
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef __mozilla_ProcInfo_h
7 #define __mozilla_ProcInfo_h
9 #include <base/process.h>
10 #include <stdint.h>
11 #include "mozilla/dom/BindingDeclarations.h"
12 #include "mozilla/dom/ChromeUtilsBinding.h"
13 #include "mozilla/dom/ipc/IdType.h"
14 #include "mozilla/HashTable.h"
15 #include "mozilla/MozPromise.h"
17 namespace mozilla {
19 namespace ipc {
20 class GeckoChildProcessHost;
23 /**
24 * Return the number of milliseconds of CPU time used since process start.
26 * @return NS_OK on success.
28 nsresult GetCpuTimeSinceProcessStartInMs(uint64_t* aResult);
30 /**
31 * Return the number of milliseconds of GPU time used since process start.
33 * @return NS_OK on success.
35 nsresult GetGpuTimeSinceProcessStartInMs(uint64_t* aResult);
37 // Process types. When updating this enum, please make sure to update
38 // WebIDLProcType, ChromeUtils::RequestProcInfo and ProcTypeToWebIDL to
39 // mirror the changes.
40 enum class ProcType {
41 // These must match the ones in RemoteType.h, and E10SUtils.sys.mjs
42 Web,
43 WebIsolated,
44 File,
45 Extension,
46 PrivilegedAbout,
47 PrivilegedMozilla,
48 WebCOOPCOEP,
49 WebServiceWorker,
50 Inference,
51 // the rest matches GeckoProcessTypes.h
52 #define GECKO_PROCESS_TYPE(enum_value, enum_name, string_name, proc_typename, \
53 process_bin_type, procinfo_typename, \
54 webidl_typename, allcaps_name) \
55 procinfo_typename,
56 #define SKIP_PROCESS_TYPE_CONTENT
57 #ifndef MOZ_ENABLE_FORKSERVER
58 # define SKIP_PROCESS_TYPE_FORKSERVER
59 #endif // MOZ_ENABLE_FORKSERVER
60 #include "mozilla/GeckoProcessTypes.h"
61 #undef SKIP_PROCESS_TYPE_CONTENT
62 #ifndef MOZ_ENABLE_FORKSERVER
63 # undef SKIP_PROCESS_TYPE_FORKSERVER
64 #endif // MOZ_ENABLE_FORKSERVER
65 #undef GECKO_PROCESS_TYPE
66 Preallocated,
67 // Unknown type of process
68 Unknown,
69 Max = Unknown,
72 using UtilityActorName = mozilla::dom::WebIDLUtilityActorName;
74 // String that will be used e.g. to annotate crash reports
75 nsCString GetUtilityActorName(const UtilityActorName aActorName);
77 #ifdef XP_WIN
78 int GetCpuFrequencyMHz();
79 #endif
81 /* Get the CPU frequency to use to convert cycle time values to actual time.
82 * @returns the TSC (Time Stamp Counter) frequency in MHz, or 0 if converting
83 * cycle time values should not be attempted. */
84 int GetCycleTimeFrequencyMHz();
86 struct ThreadInfo {
87 // Thread Id.
88 base::ProcessId tid = 0;
89 // Thread name, if any.
90 nsString name;
91 // CPU time in ns.
92 uint64_t cpuTime = 0;
93 // CPU time in cycles if available.
94 uint64_t cpuCycleCount = 0;
97 // Info on a DOM window.
98 struct WindowInfo {
99 explicit WindowInfo()
100 : outerWindowId(0),
101 documentURI(nullptr),
102 documentTitle(u""_ns),
103 isProcessRoot(false),
104 isInProcess(false) {}
105 WindowInfo(uint64_t aOuterWindowId, nsIURI* aDocumentURI,
106 nsAString&& aDocumentTitle, bool aIsProcessRoot, bool aIsInProcess)
107 : outerWindowId(aOuterWindowId),
108 documentURI(aDocumentURI),
109 documentTitle(std::move(aDocumentTitle)),
110 isProcessRoot(aIsProcessRoot),
111 isInProcess(aIsInProcess) {}
113 // Internal window id.
114 const uint64_t outerWindowId;
116 // URI of the document.
117 const nsCOMPtr<nsIURI> documentURI;
119 // Title of the document.
120 const nsString documentTitle;
122 // True if this is the toplevel window of the process.
123 // Note that this may be an iframe from another process.
124 const bool isProcessRoot;
126 const bool isInProcess;
129 // Info on a Utility process actor
130 struct UtilityInfo {
131 explicit UtilityInfo() : actorName(UtilityActorName::Unknown) {}
132 explicit UtilityInfo(UtilityActorName aActorName) : actorName(aActorName) {}
133 const UtilityActorName actorName;
136 struct ProcInfo {
137 // Process Id
138 base::ProcessId pid = 0;
139 // Child Id as defined by Firefox when a child process is created.
140 dom::ContentParentId childId;
141 // Process type
142 ProcType type;
143 // Origin, if any
144 nsCString origin;
145 // Memory size in bytes.
146 uint64_t memory = 0;
147 // CPU time in ns.
148 uint64_t cpuTime = 0;
149 uint64_t cpuCycleCount = 0;
150 // Threads owned by this process.
151 CopyableTArray<ThreadInfo> threads;
152 // DOM windows represented by this process.
153 CopyableTArray<WindowInfo> windows;
154 // Utility process actors, empty for non Utility process
155 CopyableTArray<UtilityInfo> utilityActors;
158 typedef MozPromise<mozilla::HashMap<base::ProcessId, ProcInfo>, nsresult, true>
159 ProcInfoPromise;
162 * Data we need to request process info (e.g. CPU usage, memory usage)
163 * from the operating system and populate the resulting `ProcInfo`.
165 * Note that this structure contains a mix of:
166 * - low-level handles that we need to request low-level process info
167 * (`aChildTask` on macOS, `aPid` on other platforms); and
168 * - high-level data that we already acquired while looking for
169 * `aPid`/`aChildTask` and that we will need further down the road.
171 struct ProcInfoRequest {
172 ProcInfoRequest(base::ProcessId aPid, ProcType aProcessType,
173 const nsACString& aOrigin, nsTArray<WindowInfo>&& aWindowInfo,
174 nsTArray<UtilityInfo>&& aUtilityInfo, uint32_t aChildId = 0
175 #ifdef XP_DARWIN
177 mach_port_t aChildTask = 0
178 #endif // XP_DARWIN
180 : pid(aPid),
181 processType(aProcessType),
182 origin(aOrigin),
183 windowInfo(std::move(aWindowInfo)),
184 utilityInfo(std::move(aUtilityInfo)),
185 childId(aChildId)
186 #ifdef XP_DARWIN
188 childTask(aChildTask)
189 #endif // XP_DARWIN
192 const base::ProcessId pid;
193 const ProcType processType;
194 const nsCString origin;
195 const nsTArray<WindowInfo> windowInfo;
196 const nsTArray<UtilityInfo> utilityInfo;
197 // If the process is a child, its child id, otherwise `0`.
198 const int32_t childId;
199 #ifdef XP_DARWIN
200 const mach_port_t childTask;
201 #endif // XP_DARWIN
205 * Batch a request for low-level information on Gecko processes.
207 * # Request
209 * Argument `aRequests` is a list of processes, along with high-level data
210 * we have already obtained on them and that we need to populate the
211 * resulting array of `ProcInfo`.
213 * # Result
215 * This call succeeds (possibly with missing data, see below) unless we
216 * cannot allocate memory.
218 * # Performance
220 * - This call is always executed on a background thread.
221 * - This call does NOT wake up children processes.
222 * - This function is sometimes observably slow to resolve, in particular
223 * under Windows.
225 * # Error-handling and race conditions
227 * Requesting low-level information on a process and its threads is inherently
228 * subject to race conditions. Typically, if a process or a thread is killed
229 * while we're preparing to fetch information, we can easily end up with
230 * system/lib calls that return failures.
232 * For this reason, this API assumes that errors when placing a system/lib call
233 * are likely and normal. When some information cannot be obtained, the API will
234 * simply skip over said information.
236 * Note that due to different choices by OSes, the exact information we skip may
237 * vary across platforms. For instance, under Unix, failing to access the
238 * threads of a process will cause us to skip all data on the process, while
239 * under Windows, process information will be returned without thread
240 * information.
242 RefPtr<ProcInfoPromise> GetProcInfo(nsTArray<ProcInfoRequest>&& aRequests);
245 * Synchronous version of GetProcInfo.
247 ProcInfoPromise::ResolveOrRejectValue GetProcInfoSync(
248 nsTArray<ProcInfoRequest>&& aRequests);
251 * Utility function: copy data from a `ProcInfo` and into either a
252 * `ParentProcInfoDictionary` or a `ChildProcInfoDictionary`.
254 template <typename T>
255 nsresult CopySysProcInfoToDOM(const ProcInfo& source, T* dest) {
256 // Copy system info.
257 dest->mPid = source.pid;
258 dest->mMemory = source.memory;
259 dest->mCpuTime = source.cpuTime;
260 dest->mCpuCycleCount = source.cpuCycleCount;
262 // Copy thread info.
263 mozilla::dom::Sequence<mozilla::dom::ThreadInfoDictionary> threads;
264 for (const ThreadInfo& entry : source.threads) {
265 mozilla::dom::ThreadInfoDictionary* thread =
266 threads.AppendElement(fallible);
267 if (NS_WARN_IF(!thread)) {
268 return NS_ERROR_OUT_OF_MEMORY;
270 thread->mCpuTime = entry.cpuTime;
271 thread->mCpuCycleCount = entry.cpuCycleCount;
272 thread->mTid = entry.tid;
273 thread->mName.Assign(entry.name);
275 dest->mThreads = std::move(threads);
276 return NS_OK;
279 } // namespace mozilla
280 #endif // ProcInfo_h