1a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin/* 2a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * 4a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * Use of this source code is governed by a BSD-style license 5a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * that can be found in the LICENSE file in the root of the source 6a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * tree. An additional intellectual property rights grant can be found 7a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * in the file PATENTS. All contributing project authors may 8a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin * be found in the AUTHORS file in the root of the source tree. 9a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin */ 10a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 11a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "cpu_win.h" 12a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 13a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#define _WIN32_DCOM 14a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 15a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include <assert.h> 16a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include <iostream> 17a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include <Wbemidl.h> 18a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 19a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#pragma comment(lib, "wbemuuid.lib") 20a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 21a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "condition_variable_wrapper.h" 22a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "critical_section_wrapper.h" 23a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "event_wrapper.h" 24a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin#include "thread_wrapper.h" 25a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 26a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinnamespace webrtc { 27a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word32 CpuWindows::CpuUsage() 28a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 29a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (!has_initialized_) 30a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 31a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return -1; 32a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 33a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Last element is the average 34a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return cpu_usage_[number_of_objects_ - 1]; 35a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 36a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 37a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinWebRtc_Word32 CpuWindows::CpuUsageMultiCore(WebRtc_UWord32& num_cores, 38a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin WebRtc_UWord32*& cpu_usage) 39a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 40a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (has_terminated_) { 41a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin num_cores = 0; 42a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_usage = NULL; 43a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return -1; 44a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 45a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (!has_initialized_) 46a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 47a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin num_cores = 0; 48a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_usage = NULL; 49a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return -1; 50a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 51a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin num_cores = number_of_objects_ - 1; 52a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_usage = cpu_usage_; 53a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return cpu_usage_[number_of_objects_-1]; 54a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 55a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 56a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinCpuWindows::CpuWindows() 57a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin : cpu_polling_thread(NULL), 58a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin initialize_(true), 59a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin has_initialized_(false), 60a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin terminate_(false), 61a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin has_terminated_(false), 62a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_usage_(NULL), 63a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_access_(NULL), 64a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin number_of_objects_(0), 65a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_usage_handle_(0), 66a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin previous_processor_timestamp_(NULL), 67a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin timestamp_sys_100_ns_handle_(0), 68a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin previous_100ns_timestamp_(NULL), 69a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_service_(NULL), 70a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_service_proxy_(NULL), 71a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_refresher_(NULL), 72a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_(NULL) 73a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 74a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // All resources are allocated in PollingCpu(). 75a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (AllocateComplexDataTypes()) 76a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 77a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin StartPollingCpu(); 78a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 79a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin else 80a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 81a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin assert(false); 82a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 83a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 84a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 85a6451827d543eb00824bc95097e47d0aac51ae93Alexander GutkinCpuWindows::~CpuWindows() 86a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 87a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // All resources are reclaimed in StopPollingCpu(). 88a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin StopPollingCpu(); 89a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin DeAllocateComplexDataTypes(); 90a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 91a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 92a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool CpuWindows::AllocateComplexDataTypes() 93a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 94a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_polling_thread = ThreadWrapper::CreateThread( 95a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin CpuWindows::Process, 96a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin reinterpret_cast<void*>(this), 97a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin kNormalPriority, 98a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin "CpuWindows"); 99a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin init_crit_ = CriticalSectionWrapper::CreateCriticalSection(); 100a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin init_cond_ = ConditionVariableWrapper::CreateConditionVariable(); 101a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin terminate_crit_ = CriticalSectionWrapper::CreateCriticalSection(); 102a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin terminate_cond_ = ConditionVariableWrapper::CreateConditionVariable(); 103a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin sleep_event = EventWrapper::Create(); 104a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return (cpu_polling_thread != NULL) && (init_crit_ != NULL) && 105a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin (init_cond_ != NULL) && (terminate_crit_ != NULL) && 106a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin (terminate_cond_ != NULL) && (sleep_event != NULL); 107a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 108a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 109a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinvoid CpuWindows::DeAllocateComplexDataTypes() 110a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 111a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (sleep_event != NULL) 112a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 113a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete sleep_event; 114a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin sleep_event = NULL; 115a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 116a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (terminate_cond_ != NULL) 117a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 118a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete terminate_cond_; 119a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin terminate_cond_ = NULL; 120a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 121a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (terminate_crit_ != NULL) 122a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 123a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete terminate_crit_; 124a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin terminate_crit_ = NULL; 125a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 126a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (init_cond_ != NULL) 127a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 128a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete init_cond_; 129a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin init_cond_ = NULL; 130a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 131a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (init_crit_ != NULL) 132a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 133a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete init_crit_; 134a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin init_crit_ = NULL; 135a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 136a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (cpu_polling_thread != NULL) 137a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 138a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete cpu_polling_thread; 139a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_polling_thread = NULL; 140a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 141a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 142a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 143a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinvoid CpuWindows::StartPollingCpu() 144a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 145a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin unsigned int dummy_id = 0; 146a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (!cpu_polling_thread->Start(dummy_id)) 147a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 148a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin initialize_ = false; 149a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin has_terminated_ = true; 150a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin assert(false); 151a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 152a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 153a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 154a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool CpuWindows::StopPollingCpu() 155a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 156a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 157a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // If StopPollingCpu is called immediately after StartPollingCpu() it is 158a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // possible that cpu_polling_thread is in the process of initializing. 159a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Let initialization finish to avoid getting into a bad state. 160a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin CriticalSectionScoped cs(init_crit_); 161a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin while(initialize_) 162a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 163a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin init_cond_->SleepCS(*init_crit_); 164a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 165a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 166a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 167a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin CriticalSectionScoped cs(terminate_crit_); 168a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin terminate_ = true; 169a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin sleep_event->Set(); 170a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin while (!has_terminated_) 171a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 172a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin terminate_cond_->SleepCS(*terminate_crit_); 173a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 174a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_polling_thread->Stop(); 175a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete cpu_polling_thread; 176a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_polling_thread = NULL; 177a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return true; 178a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 179a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 180a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool CpuWindows::Process(void* thread_object) 181a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 182a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return reinterpret_cast<CpuWindows*>(thread_object)->ProcessImpl(); 183a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 184a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 185a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool CpuWindows::ProcessImpl() 186a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 187a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 188a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin CriticalSectionScoped cs(terminate_crit_); 189a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (terminate_) 190a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 191a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin Terminate(); 192a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin terminate_cond_->WakeAll(); 193a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 194a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 195a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 196a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Initialize on first iteration 197a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (initialize_) 198a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 199a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin CriticalSectionScoped cs(init_crit_); 200a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin initialize_ = false; 201a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const bool success = Initialize(); 202a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin init_cond_->WakeAll(); 203a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (!success || !has_initialized_) 204a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 205a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin has_initialized_ = false; 206a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin terminate_ = true; 207a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return true; 208a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 209a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 210a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Approximately one seconds sleep for each CPU measurement. Precision is 211a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // not important. 1 second refresh rate is also used by Performance Monitor 212a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // (perfmon). 213a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if(kEventTimeout != sleep_event->Wait(1000)) 214a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 215a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Terminating. No need to update CPU usage. 216a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin assert(terminate_); 217a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return true; 218a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 219a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 220a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // UpdateCpuUsage() returns false if a single (or more) CPU read(s) failed. 221a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Not a major problem if it happens. 222a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin UpdateCpuUsage(); 223a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return true; 224a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 225a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 226a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool CpuWindows::CreateWmiConnection() 227a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 228a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin IWbemLocator* service_locator = NULL; 229a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL, 230a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin CLSCTX_INPROC_SERVER, IID_IWbemLocator, 231a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin reinterpret_cast<void**> (&service_locator)); 232a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (FAILED(hr)) 233a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 234a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 235a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 236a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // To get the WMI service specify the WMI namespace. 237a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin BSTR wmi_namespace = SysAllocString(L"\\\\.\\root\\cimv2"); 238a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (wmi_namespace == NULL) 239a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 240a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // This type of failure signifies running out of memory. 241a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin service_locator->Release(); 242a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 243a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 244a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin hr = service_locator->ConnectServer(wmi_namespace, NULL, NULL, NULL, 0L, 245a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin NULL, NULL, &wbem_service_); 246a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin SysFreeString(wmi_namespace); 247a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin service_locator->Release(); 248a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return !FAILED(hr); 249a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 250a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 251a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin// Sets up WMI refresher and enum 252a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool CpuWindows::CreatePerfOsRefresher() 253a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 254a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Create refresher. 255a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin HRESULT hr = CoCreateInstance(CLSID_WbemRefresher, NULL, 256a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin CLSCTX_INPROC_SERVER, IID_IWbemRefresher, 257a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin reinterpret_cast<void**> (&wbem_refresher_)); 258a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (FAILED(hr)) 259a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 260a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 261a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 262a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Create PerfOS_Processor enum. 263a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin IWbemConfigureRefresher* wbem_refresher_config = NULL; 264a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin hr = wbem_refresher_->QueryInterface( 265a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin IID_IWbemConfigureRefresher, 266a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin reinterpret_cast<void**> (&wbem_refresher_config)); 267a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (FAILED(hr)) 268a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 269a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 270a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 271a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 272a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Create a proxy to the IWbemServices so that a local authentication 273a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // can be set up (this is needed to be able to successfully call 274a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // IWbemConfigureRefresher::AddEnum). Setting authentication with 275a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // CoInitializeSecurity is process-wide (which is too intrusive). 276a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin hr = CoCopyProxy(static_cast<IUnknown*> (wbem_service_), 277a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin reinterpret_cast<IUnknown**> (&wbem_service_proxy_)); 278a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if(FAILED(hr)) 279a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 280a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 281a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 282a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Set local authentication. 283a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // RPC_C_AUTHN_WINNT means using NTLM instead of Kerberos which is default. 284a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin hr = CoSetProxyBlanket(static_cast<IUnknown*> (wbem_service_proxy_), 285a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, 286a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin RPC_C_AUTHN_LEVEL_DEFAULT, 287a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); 288a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if(FAILED(hr)) 289a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 290a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 291a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 292a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 293a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Don't care about the particular id for the enum. 294a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin long enum_id = 0; 295a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin hr = wbem_refresher_config->AddEnum(wbem_service_proxy_, 296a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin L"Win32_PerfRawData_PerfOS_Processor", 297a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 0, NULL, &wbem_enum_, &enum_id); 298a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_refresher_config->Release(); 299a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_refresher_config = NULL; 300a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return !FAILED(hr); 301a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 302a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 303a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin// Have to pull the first round of data to be able set the handles. 304a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool CpuWindows::CreatePerfOsCpuHandles() 305a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 306a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Update the refresher so that there is data available in wbem_enum_. 307a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_refresher_->Refresh(0L); 308a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 309a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // The number of enumerators is the number of processor + 1 (the total). 310a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // This is unknown at this point. 311a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin DWORD number_returned = 0; 312a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin HRESULT hr = wbem_enum_->GetObjects(0L, number_of_objects_, 313a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_access_, &number_returned); 314a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // number_returned indicates the number of enumerators that are needed. 315a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (hr == WBEM_E_BUFFER_TOO_SMALL && 316a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin number_returned > number_of_objects_) 317a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 318a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Allocate the number IWbemObjectAccess asked for by the 319a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // GetObjects(..) function. 320a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_access_ = new IWbemObjectAccess*[number_returned]; 321a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_usage_ = new WebRtc_UWord32[number_returned]; 322a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin previous_processor_timestamp_ = new unsigned __int64[number_returned]; 323a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin previous_100ns_timestamp_ = new unsigned __int64[number_returned]; 324a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if ((wbem_enum_access_ == NULL) || (cpu_usage_ == NULL) || 325a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin (previous_processor_timestamp_ == NULL) || 326a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin (previous_100ns_timestamp_ == NULL)) 327a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 328a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Out of memory. 329a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 330a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 331a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 332a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin SecureZeroMemory(wbem_enum_access_, number_returned * 333a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin sizeof(IWbemObjectAccess*)); 334a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin memset(cpu_usage_, 0, sizeof(int) * number_returned); 335a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin memset(previous_processor_timestamp_, 0, sizeof(unsigned __int64) * 336a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin number_returned); 337a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin memset(previous_100ns_timestamp_, 0, sizeof(unsigned __int64) * 338a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin number_returned); 339a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 340a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin number_of_objects_ = number_returned; 341a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Read should be successfull now that memory has been allocated. 342a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin hr = wbem_enum_->GetObjects(0L, number_of_objects_, wbem_enum_access_, 343a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin &number_returned); 344a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (FAILED(hr)) 345a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 346a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 347a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 348a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 349a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin else 350a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 351a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // 0 enumerators should not be enough. Something has gone wrong here. 352a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 353a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 354a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 355a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Get the enumerator handles that are needed for calculating CPU usage. 356a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin CIMTYPE cpu_usage_type; 357a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin hr = wbem_enum_access_[0]->GetPropertyHandle(L"PercentProcessorTime", 358a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin &cpu_usage_type, 359a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin &cpu_usage_handle_); 360a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (FAILED(hr)) 361a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 362a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 363a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 364a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin CIMTYPE timestamp_sys_100_ns_type; 365a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin hr = wbem_enum_access_[0]->GetPropertyHandle(L"TimeStamp_Sys100NS", 366a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin ×tamp_sys_100_ns_type, 367a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin ×tamp_sys_100_ns_handle_); 368a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return !FAILED(hr); 369a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 370a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 371a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool CpuWindows::Initialize() 372a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 373a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (terminate_) 374a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 375a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 376a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 377a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Initialize COM library. 378a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin HRESULT hr = CoInitializeEx(NULL,COINIT_MULTITHREADED); 379a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (FAILED(hr)) 380a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 381a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 382a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 383a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (FAILED(hr)) 384a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 385a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 386a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 387a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 388a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (!CreateWmiConnection()) 389a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 390a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 391a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 392a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (!CreatePerfOsRefresher()) 393a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 394a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 395a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 396a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (!CreatePerfOsCpuHandles()) 397a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 398a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 399a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 400a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin has_initialized_ = true; 401a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return true; 402a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 403a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 404a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool CpuWindows::Terminate() 405a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 406a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (has_terminated_) 407a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 408a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 409a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 410a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Reverse order of Initialize(). 411a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Some compilers complain about deleting NULL though it's well defined 412a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (previous_100ns_timestamp_ != NULL) 413a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 414a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete[] previous_100ns_timestamp_; 415a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin previous_100ns_timestamp_ = NULL; 416a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 417a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (previous_processor_timestamp_ != NULL) 418a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 419a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete[] previous_processor_timestamp_; 420a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin previous_processor_timestamp_ = NULL; 421a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 422a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (cpu_usage_ != NULL) 423a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 424a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete[] cpu_usage_; 425a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_usage_ = NULL; 426a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 427a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (wbem_enum_access_ != NULL) 428a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 429a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin for (DWORD i = 0; i < number_of_objects_; i++) 430a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 431a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if(wbem_enum_access_[i] != NULL) 432a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 433a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_access_[i]->Release(); 434a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 435a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 436a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin delete[] wbem_enum_access_; 437a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_access_ = NULL; 438a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 439a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (wbem_enum_ != NULL) 440a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 441a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_->Release(); 442a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_ = NULL; 443a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 444a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (wbem_refresher_ != NULL) 445a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 446a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_refresher_->Release(); 447a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_refresher_ = NULL; 448a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 449a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (wbem_service_proxy_ != NULL) 450a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 451a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_service_proxy_->Release(); 452a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_service_proxy_ = NULL; 453a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 454a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (wbem_service_ != NULL) 455a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 456a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_service_->Release(); 457a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_service_ = NULL; 458a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 459a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // CoUninitialized should be called once for every CoInitializeEx. 460a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Regardless if it failed or not. 461a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin CoUninitialize(); 462a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin has_terminated_ = true; 463a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return true; 464a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 465a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 466a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkinbool CpuWindows::UpdateCpuUsage() 467a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin{ 468a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_refresher_->Refresh(0L); 469a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin DWORD number_returned = 0; 470a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin HRESULT hr = wbem_enum_->GetObjects(0L, number_of_objects_, 471a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_access_,&number_returned); 472a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (FAILED(hr)) 473a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 474a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // wbem_enum_access_ has already been allocated. Unless the number of 475a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // CPUs change runtime this should not happen. 476a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return false; 477a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 478a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin unsigned __int64 cpu_usage = 0; 479a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin unsigned __int64 timestamp_100ns = 0; 480a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin bool returnValue = true; 481a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin for (DWORD i = 0; i < number_returned; i++) 482a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 483a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin hr = wbem_enum_access_[i]->ReadQWORD(cpu_usage_handle_,&cpu_usage); 484a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (FAILED(hr)) 485a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 486a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin returnValue = false; 487a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 488a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin hr = wbem_enum_access_[i]->ReadQWORD(timestamp_sys_100_ns_handle_, 489a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin ×tamp_100ns); 490a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (FAILED(hr)) 491a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 492a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin returnValue = false; 493a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 494a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_access_[i]->Release(); 495a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin wbem_enum_access_[i] = NULL; 496a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 497a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const bool wrapparound = 498a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin (previous_processor_timestamp_[i] > cpu_usage) || 499a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin (previous_100ns_timestamp_[i] > timestamp_100ns); 500a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const bool first_time = (previous_processor_timestamp_[i] == 0) || 501a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin (previous_100ns_timestamp_[i] == 0); 502a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (wrapparound || first_time) 503a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 504a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin previous_processor_timestamp_[i] = cpu_usage; 505a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin previous_100ns_timestamp_[i] = timestamp_100ns; 506a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin continue; 507a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 508a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const unsigned __int64 processor_timestamp_delta = 509a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_usage - previous_processor_timestamp_[i]; 510a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const unsigned __int64 timestamp_100ns_delta = 511a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin timestamp_100ns - previous_100ns_timestamp_[i]; 512a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 513a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin if (processor_timestamp_delta >= timestamp_100ns_delta) 514a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin { 515a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_usage_[i] = 0; 516a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } else { 517a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // Quotient must be float since the division is guaranteed to yield 518a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin // a value between 0 and 1 which is 0 in integer division. 519a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin const float delta_quotient = 520a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin static_cast<float>(processor_timestamp_delta) / 521a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin static_cast<float>(timestamp_100ns_delta); 522a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin cpu_usage_[i] = 100 - static_cast<WebRtc_UWord32>(delta_quotient * 523a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin 100); 524a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 525a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin previous_processor_timestamp_[i] = cpu_usage; 526a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin previous_100ns_timestamp_[i] = timestamp_100ns; 527a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin } 528a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin return returnValue; 529a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} 530a6451827d543eb00824bc95097e47d0aac51ae93Alexander Gutkin} // namespace webrtc 531