blob: 54e4301dbf0b8bd6a5c5da9b4b496a6c65f39864 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/extensions/api/system_cpu/cpu_info_provider.h"
#include <windows.h>
#include <winternl.h>
#include "base/sys_info.h"
namespace extensions {
namespace {
const wchar_t kNtdll[] = L"ntdll.dll";
const char kNtQuerySystemInformationName[] = "NtQuerySystemInformation";
// See MSDN about NtQuerySystemInformation definition.
typedef DWORD (WINAPI *NtQuerySystemInformationPF)(DWORD system_info_class,
PVOID system_info,
ULONG system_info_length,
PULONG return_length);
} // namespace
bool CpuInfoProvider::QueryCpuTimePerProcessor(
std::vector<linked_ptr<api::system_cpu::ProcessorInfo> >* infos) {
DCHECK(infos);
HMODULE ntdll = GetModuleHandle(kNtdll);
CHECK(ntdll != NULL);
NtQuerySystemInformationPF NtQuerySystemInformation =
reinterpret_cast<NtQuerySystemInformationPF>(
::GetProcAddress(ntdll, kNtQuerySystemInformationName));
CHECK(NtQuerySystemInformation != NULL);
int num_of_processors = base::SysInfo::NumberOfProcessors();
scoped_ptr<SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[]> processor_info(
new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[num_of_processors]);
ULONG returned_bytes = 0, bytes =
sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * num_of_processors;
if (!NT_SUCCESS(NtQuerySystemInformation(
SystemProcessorPerformanceInformation,
processor_info.get(), bytes, &returned_bytes)))
return false;
int returned_num_of_processors =
returned_bytes / sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
if (returned_num_of_processors != num_of_processors)
return false;
DCHECK_EQ(num_of_processors, static_cast<int>(infos->size()));
for (int i = 0; i < returned_num_of_processors; ++i) {
double kernel = static_cast<double>(processor_info[i].KernelTime.QuadPart),
user = static_cast<double>(processor_info[i].UserTime.QuadPart),
idle = static_cast<double>(processor_info[i].IdleTime.QuadPart);
// KernelTime needs to be fixed-up, because it includes both idle time and
// real kernel time.
infos->at(i)->usage.kernel = kernel - idle;
infos->at(i)->usage.user = user;
infos->at(i)->usage.idle = idle;
infos->at(i)->usage.total = kernel + user;
}
return true;
}
} // namespace extensions