1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/process/process_metrics.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <windows.h> // Must be in front of other Windows header files.
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include <psapi.h>
10*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
11*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
12*6777b538SAndroid Build Coastguard Worker #include <winternl.h>
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker #include <algorithm>
15*6777b538SAndroid Build Coastguard Worker
16*6777b538SAndroid Build Coastguard Worker #include "base/debug/crash_logging.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/system/sys_info.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/threading/scoped_blocking_call.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
23*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
24*6777b538SAndroid Build Coastguard Worker
25*6777b538SAndroid Build Coastguard Worker namespace base {
26*6777b538SAndroid Build Coastguard Worker namespace {
27*6777b538SAndroid Build Coastguard Worker
28*6777b538SAndroid Build Coastguard Worker // ntstatus.h conflicts with windows.h so define this locally.
29*6777b538SAndroid Build Coastguard Worker #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
30*6777b538SAndroid Build Coastguard Worker
31*6777b538SAndroid Build Coastguard Worker // Definition of this struct is taken from the book:
32*6777b538SAndroid Build Coastguard Worker // Windows NT/200, Native API reference, Gary Nebbett
33*6777b538SAndroid Build Coastguard Worker struct SYSTEM_PERFORMANCE_INFORMATION {
34*6777b538SAndroid Build Coastguard Worker // Total idle time of all processes in the system (units of 100 ns).
35*6777b538SAndroid Build Coastguard Worker LARGE_INTEGER IdleTime;
36*6777b538SAndroid Build Coastguard Worker // Number of bytes read (by all call to ZwReadFile).
37*6777b538SAndroid Build Coastguard Worker LARGE_INTEGER ReadTransferCount;
38*6777b538SAndroid Build Coastguard Worker // Number of bytes written (by all call to ZwWriteFile).
39*6777b538SAndroid Build Coastguard Worker LARGE_INTEGER WriteTransferCount;
40*6777b538SAndroid Build Coastguard Worker // Number of bytes transferred (e.g. DeviceIoControlFile)
41*6777b538SAndroid Build Coastguard Worker LARGE_INTEGER OtherTransferCount;
42*6777b538SAndroid Build Coastguard Worker // The amount of read operations.
43*6777b538SAndroid Build Coastguard Worker ULONG ReadOperationCount;
44*6777b538SAndroid Build Coastguard Worker // The amount of write operations.
45*6777b538SAndroid Build Coastguard Worker ULONG WriteOperationCount;
46*6777b538SAndroid Build Coastguard Worker // The amount of other operations.
47*6777b538SAndroid Build Coastguard Worker ULONG OtherOperationCount;
48*6777b538SAndroid Build Coastguard Worker // The number of pages of physical memory available to processes running on
49*6777b538SAndroid Build Coastguard Worker // the system.
50*6777b538SAndroid Build Coastguard Worker ULONG AvailablePages;
51*6777b538SAndroid Build Coastguard Worker ULONG TotalCommittedPages;
52*6777b538SAndroid Build Coastguard Worker ULONG TotalCommitLimit;
53*6777b538SAndroid Build Coastguard Worker ULONG PeakCommitment;
54*6777b538SAndroid Build Coastguard Worker ULONG PageFaults;
55*6777b538SAndroid Build Coastguard Worker ULONG WriteCopyFaults;
56*6777b538SAndroid Build Coastguard Worker ULONG TransitionFaults;
57*6777b538SAndroid Build Coastguard Worker ULONG CacheTransitionFaults;
58*6777b538SAndroid Build Coastguard Worker ULONG DemandZeroFaults;
59*6777b538SAndroid Build Coastguard Worker // The number of pages read from disk to resolve page faults.
60*6777b538SAndroid Build Coastguard Worker ULONG PagesRead;
61*6777b538SAndroid Build Coastguard Worker // The number of read operations initiated to resolve page faults.
62*6777b538SAndroid Build Coastguard Worker ULONG PageReadIos;
63*6777b538SAndroid Build Coastguard Worker ULONG CacheReads;
64*6777b538SAndroid Build Coastguard Worker ULONG CacheIos;
65*6777b538SAndroid Build Coastguard Worker // The number of pages written to the system's pagefiles.
66*6777b538SAndroid Build Coastguard Worker ULONG PagefilePagesWritten;
67*6777b538SAndroid Build Coastguard Worker // The number of write operations performed on the system's pagefiles.
68*6777b538SAndroid Build Coastguard Worker ULONG PagefilePageWriteIos;
69*6777b538SAndroid Build Coastguard Worker ULONG MappedFilePagesWritten;
70*6777b538SAndroid Build Coastguard Worker ULONG MappedFilePageWriteIos;
71*6777b538SAndroid Build Coastguard Worker ULONG PagedPoolUsage;
72*6777b538SAndroid Build Coastguard Worker ULONG NonPagedPoolUsage;
73*6777b538SAndroid Build Coastguard Worker ULONG PagedPoolAllocs;
74*6777b538SAndroid Build Coastguard Worker ULONG PagedPoolFrees;
75*6777b538SAndroid Build Coastguard Worker ULONG NonPagedPoolAllocs;
76*6777b538SAndroid Build Coastguard Worker ULONG NonPagedPoolFrees;
77*6777b538SAndroid Build Coastguard Worker ULONG TotalFreeSystemPtes;
78*6777b538SAndroid Build Coastguard Worker ULONG SystemCodePage;
79*6777b538SAndroid Build Coastguard Worker ULONG TotalSystemDriverPages;
80*6777b538SAndroid Build Coastguard Worker ULONG TotalSystemCodePages;
81*6777b538SAndroid Build Coastguard Worker ULONG SmallNonPagedLookasideListAllocateHits;
82*6777b538SAndroid Build Coastguard Worker ULONG SmallPagedLookasideListAllocateHits;
83*6777b538SAndroid Build Coastguard Worker ULONG Reserved3;
84*6777b538SAndroid Build Coastguard Worker ULONG MmSystemCachePage;
85*6777b538SAndroid Build Coastguard Worker ULONG PagedPoolPage;
86*6777b538SAndroid Build Coastguard Worker ULONG SystemDriverPage;
87*6777b538SAndroid Build Coastguard Worker ULONG FastReadNoWait;
88*6777b538SAndroid Build Coastguard Worker ULONG FastReadWait;
89*6777b538SAndroid Build Coastguard Worker ULONG FastReadResourceMiss;
90*6777b538SAndroid Build Coastguard Worker ULONG FastReadNotPossible;
91*6777b538SAndroid Build Coastguard Worker ULONG FastMdlReadNoWait;
92*6777b538SAndroid Build Coastguard Worker ULONG FastMdlReadWait;
93*6777b538SAndroid Build Coastguard Worker ULONG FastMdlReadResourceMiss;
94*6777b538SAndroid Build Coastguard Worker ULONG FastMdlReadNotPossible;
95*6777b538SAndroid Build Coastguard Worker ULONG MapDataNoWait;
96*6777b538SAndroid Build Coastguard Worker ULONG MapDataWait;
97*6777b538SAndroid Build Coastguard Worker ULONG MapDataNoWaitMiss;
98*6777b538SAndroid Build Coastguard Worker ULONG MapDataWaitMiss;
99*6777b538SAndroid Build Coastguard Worker ULONG PinMappedDataCount;
100*6777b538SAndroid Build Coastguard Worker ULONG PinReadNoWait;
101*6777b538SAndroid Build Coastguard Worker ULONG PinReadWait;
102*6777b538SAndroid Build Coastguard Worker ULONG PinReadNoWaitMiss;
103*6777b538SAndroid Build Coastguard Worker ULONG PinReadWaitMiss;
104*6777b538SAndroid Build Coastguard Worker ULONG CopyReadNoWait;
105*6777b538SAndroid Build Coastguard Worker ULONG CopyReadWait;
106*6777b538SAndroid Build Coastguard Worker ULONG CopyReadNoWaitMiss;
107*6777b538SAndroid Build Coastguard Worker ULONG CopyReadWaitMiss;
108*6777b538SAndroid Build Coastguard Worker ULONG MdlReadNoWait;
109*6777b538SAndroid Build Coastguard Worker ULONG MdlReadWait;
110*6777b538SAndroid Build Coastguard Worker ULONG MdlReadNoWaitMiss;
111*6777b538SAndroid Build Coastguard Worker ULONG MdlReadWaitMiss;
112*6777b538SAndroid Build Coastguard Worker ULONG ReadAheadIos;
113*6777b538SAndroid Build Coastguard Worker ULONG LazyWriteIos;
114*6777b538SAndroid Build Coastguard Worker ULONG LazyWritePages;
115*6777b538SAndroid Build Coastguard Worker ULONG DataFlushes;
116*6777b538SAndroid Build Coastguard Worker ULONG DataPages;
117*6777b538SAndroid Build Coastguard Worker ULONG ContextSwitches;
118*6777b538SAndroid Build Coastguard Worker ULONG FirstLevelTbFills;
119*6777b538SAndroid Build Coastguard Worker ULONG SecondLevelTbFills;
120*6777b538SAndroid Build Coastguard Worker ULONG SystemCalls;
121*6777b538SAndroid Build Coastguard Worker };
122*6777b538SAndroid Build Coastguard Worker
GetImpreciseCumulativeCPUUsage(const win::ScopedHandle & process)123*6777b538SAndroid Build Coastguard Worker base::expected<TimeDelta, ProcessCPUUsageError> GetImpreciseCumulativeCPUUsage(
124*6777b538SAndroid Build Coastguard Worker const win::ScopedHandle& process) {
125*6777b538SAndroid Build Coastguard Worker FILETIME creation_time;
126*6777b538SAndroid Build Coastguard Worker FILETIME exit_time;
127*6777b538SAndroid Build Coastguard Worker FILETIME kernel_time;
128*6777b538SAndroid Build Coastguard Worker FILETIME user_time;
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard Worker if (!process.is_valid()) {
131*6777b538SAndroid Build Coastguard Worker return base::unexpected(ProcessCPUUsageError::kSystemError);
132*6777b538SAndroid Build Coastguard Worker }
133*6777b538SAndroid Build Coastguard Worker
134*6777b538SAndroid Build Coastguard Worker if (!GetProcessTimes(process.get(), &creation_time, &exit_time, &kernel_time,
135*6777b538SAndroid Build Coastguard Worker &user_time)) {
136*6777b538SAndroid Build Coastguard Worker // This should never fail when the handle is valid.
137*6777b538SAndroid Build Coastguard Worker NOTREACHED(NotFatalUntil::M125);
138*6777b538SAndroid Build Coastguard Worker return base::unexpected(ProcessCPUUsageError::kSystemError);
139*6777b538SAndroid Build Coastguard Worker }
140*6777b538SAndroid Build Coastguard Worker
141*6777b538SAndroid Build Coastguard Worker return base::ok(TimeDelta::FromFileTime(kernel_time) +
142*6777b538SAndroid Build Coastguard Worker TimeDelta::FromFileTime(user_time));
143*6777b538SAndroid Build Coastguard Worker }
144*6777b538SAndroid Build Coastguard Worker
145*6777b538SAndroid Build Coastguard Worker } // namespace
146*6777b538SAndroid Build Coastguard Worker
GetMaxFds()147*6777b538SAndroid Build Coastguard Worker size_t GetMaxFds() {
148*6777b538SAndroid Build Coastguard Worker // Windows is only limited by the amount of physical memory.
149*6777b538SAndroid Build Coastguard Worker return std::numeric_limits<size_t>::max();
150*6777b538SAndroid Build Coastguard Worker }
151*6777b538SAndroid Build Coastguard Worker
GetHandleLimit()152*6777b538SAndroid Build Coastguard Worker size_t GetHandleLimit() {
153*6777b538SAndroid Build Coastguard Worker // Rounded down from value reported here:
154*6777b538SAndroid Build Coastguard Worker // http://blogs.technet.com/b/markrussinovich/archive/2009/09/29/3283844.aspx
155*6777b538SAndroid Build Coastguard Worker return static_cast<size_t>(1 << 23);
156*6777b538SAndroid Build Coastguard Worker }
157*6777b538SAndroid Build Coastguard Worker
158*6777b538SAndroid Build Coastguard Worker // static
CreateProcessMetrics(ProcessHandle process)159*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ProcessMetrics> ProcessMetrics::CreateProcessMetrics(
160*6777b538SAndroid Build Coastguard Worker ProcessHandle process) {
161*6777b538SAndroid Build Coastguard Worker return WrapUnique(new ProcessMetrics(process));
162*6777b538SAndroid Build Coastguard Worker }
163*6777b538SAndroid Build Coastguard Worker
164*6777b538SAndroid Build Coastguard Worker base::expected<TimeDelta, ProcessCPUUsageError>
GetCumulativeCPUUsage()165*6777b538SAndroid Build Coastguard Worker ProcessMetrics::GetCumulativeCPUUsage() {
166*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_ARM64)
167*6777b538SAndroid Build Coastguard Worker // Precise CPU usage is not available on Arm CPUs because they don't support
168*6777b538SAndroid Build Coastguard Worker // constant rate TSC.
169*6777b538SAndroid Build Coastguard Worker return GetImpreciseCumulativeCPUUsage(process_);
170*6777b538SAndroid Build Coastguard Worker #else // !defined(ARCH_CPU_ARM64)
171*6777b538SAndroid Build Coastguard Worker if (!time_internal::HasConstantRateTSC()) {
172*6777b538SAndroid Build Coastguard Worker return GetImpreciseCumulativeCPUUsage(process_);
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker
175*6777b538SAndroid Build Coastguard Worker const double tsc_ticks_per_second = time_internal::TSCTicksPerSecond();
176*6777b538SAndroid Build Coastguard Worker if (tsc_ticks_per_second == 0) {
177*6777b538SAndroid Build Coastguard Worker // TSC is only initialized once TSCTicksPerSecond() is called twice 50 ms
178*6777b538SAndroid Build Coastguard Worker // apart on the same thread to get a baseline. In unit tests, it is frequent
179*6777b538SAndroid Build Coastguard Worker // for the initialization not to be complete. In production, it can also
180*6777b538SAndroid Build Coastguard Worker // theoretically happen.
181*6777b538SAndroid Build Coastguard Worker return GetImpreciseCumulativeCPUUsage(process_);
182*6777b538SAndroid Build Coastguard Worker }
183*6777b538SAndroid Build Coastguard Worker
184*6777b538SAndroid Build Coastguard Worker if (!process_.is_valid()) {
185*6777b538SAndroid Build Coastguard Worker return base::unexpected(ProcessCPUUsageError::kProcessNotFound);
186*6777b538SAndroid Build Coastguard Worker }
187*6777b538SAndroid Build Coastguard Worker
188*6777b538SAndroid Build Coastguard Worker ULONG64 process_cycle_time = 0;
189*6777b538SAndroid Build Coastguard Worker if (!QueryProcessCycleTime(process_.get(), &process_cycle_time)) {
190*6777b538SAndroid Build Coastguard Worker // This should never fail when the handle is valid.
191*6777b538SAndroid Build Coastguard Worker NOTREACHED(NotFatalUntil::M125);
192*6777b538SAndroid Build Coastguard Worker return base::unexpected(ProcessCPUUsageError::kSystemError);
193*6777b538SAndroid Build Coastguard Worker }
194*6777b538SAndroid Build Coastguard Worker
195*6777b538SAndroid Build Coastguard Worker const double process_time_seconds = process_cycle_time / tsc_ticks_per_second;
196*6777b538SAndroid Build Coastguard Worker return base::ok(Seconds(process_time_seconds));
197*6777b538SAndroid Build Coastguard Worker #endif // !defined(ARCH_CPU_ARM64)
198*6777b538SAndroid Build Coastguard Worker }
199*6777b538SAndroid Build Coastguard Worker
ProcessMetrics(ProcessHandle process)200*6777b538SAndroid Build Coastguard Worker ProcessMetrics::ProcessMetrics(ProcessHandle process) {
201*6777b538SAndroid Build Coastguard Worker if (!process) {
202*6777b538SAndroid Build Coastguard Worker // Don't try to duplicate an invalid handle.
203*6777b538SAndroid Build Coastguard Worker return;
204*6777b538SAndroid Build Coastguard Worker }
205*6777b538SAndroid Build Coastguard Worker HANDLE duplicate_handle = INVALID_HANDLE_VALUE;
206*6777b538SAndroid Build Coastguard Worker BOOL result = ::DuplicateHandle(::GetCurrentProcess(), process,
207*6777b538SAndroid Build Coastguard Worker ::GetCurrentProcess(), &duplicate_handle,
208*6777b538SAndroid Build Coastguard Worker PROCESS_QUERY_LIMITED_INFORMATION, FALSE, 0);
209*6777b538SAndroid Build Coastguard Worker if (!result) {
210*6777b538SAndroid Build Coastguard Worker // TODO(crbug.com/326136373): Remove this crash key and just CHECK(result)
211*6777b538SAndroid Build Coastguard Worker // after verifying that DuplicateHandle doesn't fail for unexpected reasons
212*6777b538SAndroid Build Coastguard Worker // in production.
213*6777b538SAndroid Build Coastguard Worker const DWORD last_error = ::GetLastError();
214*6777b538SAndroid Build Coastguard Worker SCOPED_CRASH_KEY_NUMBER("ProcessMetrics", "dup_handle_error", last_error);
215*6777b538SAndroid Build Coastguard Worker NOTREACHED(NotFatalUntil::M126);
216*6777b538SAndroid Build Coastguard Worker return;
217*6777b538SAndroid Build Coastguard Worker }
218*6777b538SAndroid Build Coastguard Worker
219*6777b538SAndroid Build Coastguard Worker process_.Set(duplicate_handle);
220*6777b538SAndroid Build Coastguard Worker }
221*6777b538SAndroid Build Coastguard Worker
GetSystemCommitCharge()222*6777b538SAndroid Build Coastguard Worker size_t GetSystemCommitCharge() {
223*6777b538SAndroid Build Coastguard Worker // Get the System Page Size.
224*6777b538SAndroid Build Coastguard Worker SYSTEM_INFO system_info;
225*6777b538SAndroid Build Coastguard Worker GetSystemInfo(&system_info);
226*6777b538SAndroid Build Coastguard Worker
227*6777b538SAndroid Build Coastguard Worker PERFORMANCE_INFORMATION info;
228*6777b538SAndroid Build Coastguard Worker if (!GetPerformanceInfo(&info, sizeof(info))) {
229*6777b538SAndroid Build Coastguard Worker DLOG(ERROR) << "Failed to fetch internal performance info.";
230*6777b538SAndroid Build Coastguard Worker return 0;
231*6777b538SAndroid Build Coastguard Worker }
232*6777b538SAndroid Build Coastguard Worker return (info.CommitTotal * system_info.dwPageSize) / 1024;
233*6777b538SAndroid Build Coastguard Worker }
234*6777b538SAndroid Build Coastguard Worker
235*6777b538SAndroid Build Coastguard Worker // This function uses the following mapping between MEMORYSTATUSEX and
236*6777b538SAndroid Build Coastguard Worker // SystemMemoryInfoKB:
237*6777b538SAndroid Build Coastguard Worker // ullTotalPhys ==> total
238*6777b538SAndroid Build Coastguard Worker // ullAvailPhys ==> avail_phys
239*6777b538SAndroid Build Coastguard Worker // ullTotalPageFile ==> swap_total
240*6777b538SAndroid Build Coastguard Worker // ullAvailPageFile ==> swap_free
GetSystemMemoryInfo(SystemMemoryInfoKB * meminfo)241*6777b538SAndroid Build Coastguard Worker bool GetSystemMemoryInfo(SystemMemoryInfoKB* meminfo) {
242*6777b538SAndroid Build Coastguard Worker MEMORYSTATUSEX mem_status;
243*6777b538SAndroid Build Coastguard Worker mem_status.dwLength = sizeof(mem_status);
244*6777b538SAndroid Build Coastguard Worker if (!::GlobalMemoryStatusEx(&mem_status)) {
245*6777b538SAndroid Build Coastguard Worker return false;
246*6777b538SAndroid Build Coastguard Worker }
247*6777b538SAndroid Build Coastguard Worker
248*6777b538SAndroid Build Coastguard Worker meminfo->total = saturated_cast<int>(mem_status.ullTotalPhys / 1024);
249*6777b538SAndroid Build Coastguard Worker meminfo->avail_phys = saturated_cast<int>(mem_status.ullAvailPhys / 1024);
250*6777b538SAndroid Build Coastguard Worker meminfo->swap_total = saturated_cast<int>(mem_status.ullTotalPageFile / 1024);
251*6777b538SAndroid Build Coastguard Worker meminfo->swap_free = saturated_cast<int>(mem_status.ullAvailPageFile / 1024);
252*6777b538SAndroid Build Coastguard Worker
253*6777b538SAndroid Build Coastguard Worker return true;
254*6777b538SAndroid Build Coastguard Worker }
255*6777b538SAndroid Build Coastguard Worker
GetMallocUsage()256*6777b538SAndroid Build Coastguard Worker size_t ProcessMetrics::GetMallocUsage() {
257*6777b538SAndroid Build Coastguard Worker // Unsupported as getting malloc usage on Windows requires iterating through
258*6777b538SAndroid Build Coastguard Worker // the heap which is slow and crashes.
259*6777b538SAndroid Build Coastguard Worker return 0;
260*6777b538SAndroid Build Coastguard Worker }
261*6777b538SAndroid Build Coastguard Worker
262*6777b538SAndroid Build Coastguard Worker SystemPerformanceInfo::SystemPerformanceInfo() = default;
263*6777b538SAndroid Build Coastguard Worker SystemPerformanceInfo::SystemPerformanceInfo(
264*6777b538SAndroid Build Coastguard Worker const SystemPerformanceInfo& other) = default;
265*6777b538SAndroid Build Coastguard Worker SystemPerformanceInfo& SystemPerformanceInfo::operator=(
266*6777b538SAndroid Build Coastguard Worker const SystemPerformanceInfo& other) = default;
267*6777b538SAndroid Build Coastguard Worker
ToDict() const268*6777b538SAndroid Build Coastguard Worker Value::Dict SystemPerformanceInfo::ToDict() const {
269*6777b538SAndroid Build Coastguard Worker Value::Dict result;
270*6777b538SAndroid Build Coastguard Worker
271*6777b538SAndroid Build Coastguard Worker // Write out uint64_t variables as doubles.
272*6777b538SAndroid Build Coastguard Worker // Note: this may discard some precision, but for JS there's no other option.
273*6777b538SAndroid Build Coastguard Worker result.Set("idle_time", strict_cast<double>(idle_time));
274*6777b538SAndroid Build Coastguard Worker result.Set("read_transfer_count", strict_cast<double>(read_transfer_count));
275*6777b538SAndroid Build Coastguard Worker result.Set("write_transfer_count", strict_cast<double>(write_transfer_count));
276*6777b538SAndroid Build Coastguard Worker result.Set("other_transfer_count", strict_cast<double>(other_transfer_count));
277*6777b538SAndroid Build Coastguard Worker result.Set("read_operation_count", strict_cast<double>(read_operation_count));
278*6777b538SAndroid Build Coastguard Worker result.Set("write_operation_count",
279*6777b538SAndroid Build Coastguard Worker strict_cast<double>(write_operation_count));
280*6777b538SAndroid Build Coastguard Worker result.Set("other_operation_count",
281*6777b538SAndroid Build Coastguard Worker strict_cast<double>(other_operation_count));
282*6777b538SAndroid Build Coastguard Worker result.Set("pagefile_pages_written",
283*6777b538SAndroid Build Coastguard Worker strict_cast<double>(pagefile_pages_written));
284*6777b538SAndroid Build Coastguard Worker result.Set("pagefile_pages_write_ios",
285*6777b538SAndroid Build Coastguard Worker strict_cast<double>(pagefile_pages_write_ios));
286*6777b538SAndroid Build Coastguard Worker result.Set("available_pages", strict_cast<double>(available_pages));
287*6777b538SAndroid Build Coastguard Worker result.Set("pages_read", strict_cast<double>(pages_read));
288*6777b538SAndroid Build Coastguard Worker result.Set("page_read_ios", strict_cast<double>(page_read_ios));
289*6777b538SAndroid Build Coastguard Worker
290*6777b538SAndroid Build Coastguard Worker return result;
291*6777b538SAndroid Build Coastguard Worker }
292*6777b538SAndroid Build Coastguard Worker
293*6777b538SAndroid Build Coastguard Worker // Retrieves performance counters from the operating system.
294*6777b538SAndroid Build Coastguard Worker // Fills in the provided |info| structure. Returns true on success.
GetSystemPerformanceInfo(SystemPerformanceInfo * info)295*6777b538SAndroid Build Coastguard Worker BASE_EXPORT bool GetSystemPerformanceInfo(SystemPerformanceInfo* info) {
296*6777b538SAndroid Build Coastguard Worker SYSTEM_PERFORMANCE_INFORMATION counters = {};
297*6777b538SAndroid Build Coastguard Worker {
298*6777b538SAndroid Build Coastguard Worker // The call to NtQuerySystemInformation might block on a lock.
299*6777b538SAndroid Build Coastguard Worker base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
300*6777b538SAndroid Build Coastguard Worker BlockingType::MAY_BLOCK);
301*6777b538SAndroid Build Coastguard Worker if (::NtQuerySystemInformation(::SystemPerformanceInformation, &counters,
302*6777b538SAndroid Build Coastguard Worker sizeof(SYSTEM_PERFORMANCE_INFORMATION),
303*6777b538SAndroid Build Coastguard Worker nullptr) != STATUS_SUCCESS) {
304*6777b538SAndroid Build Coastguard Worker return false;
305*6777b538SAndroid Build Coastguard Worker }
306*6777b538SAndroid Build Coastguard Worker }
307*6777b538SAndroid Build Coastguard Worker
308*6777b538SAndroid Build Coastguard Worker info->idle_time = static_cast<uint64_t>(counters.IdleTime.QuadPart);
309*6777b538SAndroid Build Coastguard Worker info->read_transfer_count =
310*6777b538SAndroid Build Coastguard Worker static_cast<uint64_t>(counters.ReadTransferCount.QuadPart);
311*6777b538SAndroid Build Coastguard Worker info->write_transfer_count =
312*6777b538SAndroid Build Coastguard Worker static_cast<uint64_t>(counters.WriteTransferCount.QuadPart);
313*6777b538SAndroid Build Coastguard Worker info->other_transfer_count =
314*6777b538SAndroid Build Coastguard Worker static_cast<uint64_t>(counters.OtherTransferCount.QuadPart);
315*6777b538SAndroid Build Coastguard Worker info->read_operation_count = counters.ReadOperationCount;
316*6777b538SAndroid Build Coastguard Worker info->write_operation_count = counters.WriteOperationCount;
317*6777b538SAndroid Build Coastguard Worker info->other_operation_count = counters.OtherOperationCount;
318*6777b538SAndroid Build Coastguard Worker info->pagefile_pages_written = counters.PagefilePagesWritten;
319*6777b538SAndroid Build Coastguard Worker info->pagefile_pages_write_ios = counters.PagefilePageWriteIos;
320*6777b538SAndroid Build Coastguard Worker info->available_pages = counters.AvailablePages;
321*6777b538SAndroid Build Coastguard Worker info->pages_read = counters.PagesRead;
322*6777b538SAndroid Build Coastguard Worker info->page_read_ios = counters.PageReadIos;
323*6777b538SAndroid Build Coastguard Worker
324*6777b538SAndroid Build Coastguard Worker return true;
325*6777b538SAndroid Build Coastguard Worker }
326*6777b538SAndroid Build Coastguard Worker
327*6777b538SAndroid Build Coastguard Worker } // namespace base
328