1// Copyright 2014 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#include "chrome/browser/extensions/api/system_cpu/cpu_info_provider.h" 6 7#include <windows.h> 8#include <winternl.h> 9 10#include "base/sys_info.h" 11 12namespace extensions { 13 14namespace { 15 16const wchar_t kNtdll[] = L"ntdll.dll"; 17const char kNtQuerySystemInformationName[] = "NtQuerySystemInformation"; 18 19// See MSDN about NtQuerySystemInformation definition. 20typedef DWORD (WINAPI *NtQuerySystemInformationPF)(DWORD system_info_class, 21 PVOID system_info, 22 ULONG system_info_length, 23 PULONG return_length); 24 25} // namespace 26 27bool CpuInfoProvider::QueryCpuTimePerProcessor( 28 std::vector<linked_ptr<api::system_cpu::ProcessorInfo> >* infos) { 29 DCHECK(infos); 30 31 HMODULE ntdll = GetModuleHandle(kNtdll); 32 CHECK(ntdll != NULL); 33 NtQuerySystemInformationPF NtQuerySystemInformation = 34 reinterpret_cast<NtQuerySystemInformationPF>( 35 ::GetProcAddress(ntdll, kNtQuerySystemInformationName)); 36 37 CHECK(NtQuerySystemInformation != NULL); 38 39 int num_of_processors = base::SysInfo::NumberOfProcessors(); 40 scoped_ptr<SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[]> processor_info( 41 new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[num_of_processors]); 42 43 ULONG returned_bytes = 0, bytes = 44 sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * num_of_processors; 45 if (!NT_SUCCESS(NtQuerySystemInformation( 46 SystemProcessorPerformanceInformation, 47 processor_info.get(), bytes, &returned_bytes))) 48 return false; 49 50 int returned_num_of_processors = 51 returned_bytes / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); 52 53 if (returned_num_of_processors != num_of_processors) 54 return false; 55 56 DCHECK_EQ(num_of_processors, static_cast<int>(infos->size())); 57 for (int i = 0; i < returned_num_of_processors; ++i) { 58 double kernel = static_cast<double>(processor_info[i].KernelTime.QuadPart), 59 user = static_cast<double>(processor_info[i].UserTime.QuadPart), 60 idle = static_cast<double>(processor_info[i].IdleTime.QuadPart); 61 62 // KernelTime needs to be fixed-up, because it includes both idle time and 63 // real kernel time. 64 infos->at(i)->usage.kernel = kernel - idle; 65 infos->at(i)->usage.user = user; 66 infos->at(i)->usage.idle = idle; 67 infos->at(i)->usage.total = kernel + user; 68 } 69 70 return true; 71} 72 73} // namespace extensions 74