From d480ecfbe8bced5bbfbfa44dd230fb5e635cc689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Ferenc=20Nagy-Egri?= Date: Fri, 23 Jul 2021 13:45:09 +0200 Subject: [PATCH 1/7] Per-core reading prototype --- CMakeLists.txt | 64 +++++++++++++++-- main.c | 23 +++++++ wmi.cpp | 182 +++++++++++++++++++++++++++++++++++++++++++++++++ wmi.h | 17 +++++ 4 files changed, 280 insertions(+), 6 deletions(-) create mode 100644 main.c create mode 100644 wmi.cpp create mode 100644 wmi.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e174b40..fcc802d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,62 @@ -cmake_minimum_required(VERSION 2.6) -project(NTop C) +cmake_minimum_required(VERSION 3.8) + +project(NTop + LANGUAGES + C + CXX +) option(ENABLE_UNICODE "Compile with Unicode support" OFF) -if(ENABLE_UNICODE) - add_definitions(-DUNICODE -D_UNICODE) -endif() +add_executable(${PROJECT_NAME} + ntop.c + util.c + vi.c +) + +target_compile_definitions(${PROJECT_NAME} + PRIVATE + $<$: + UNICODE + _UNICODE + > +) + +target_link_libraries(${PROJECT_NAME} + PRIVATE + WindowsApp + wbemuuid +) + +target_compile_features(${PROJECT_NAME} + PRIVATE cxx_std_17 +) + +# Temporary fix for C++/WinRT bug +target_compile_options(${PROJECT_NAME} + PRIVATE /permissive +) + +find_package(WIL CONFIG REQUIRED) + +add_executable(wmi + main.c + wmi.cpp +) + +target_link_libraries(wmi + PRIVATE + WindowsApp + wbemuuid + WIL::WIL +) + +target_compile_features(wmi + PRIVATE + cxx_std_17 +) -add_executable(NTop ntop.c util.c vi.c) +# Temporary fix for C++/WinRT bug +target_compile_options(wmi + PRIVATE /permissive +) diff --git a/main.c b/main.c new file mode 100644 index 0000000..3b92774 --- /dev/null +++ b/main.c @@ -0,0 +1,23 @@ +#include "wmi.h" + +#include + +#include +#include + +int main() +{ + struct WMI* wmi = NewWMIService(); + + int* loads = NULL; + size_t count = 0; + for(int i = 0; i < 1000 ; ++i) + { + WMIQueryProcessorTime(wmi, &loads, &count); + for(size_t c = 0 ; c < count; ++c) printf("%d\n", loads[c]); + printf("\n"); fflush(NULL); + Sleep(500); + } + + CloseWMIService(wmi); +} \ No newline at end of file diff --git a/wmi.cpp b/wmi.cpp new file mode 100644 index 0000000..66439ff --- /dev/null +++ b/wmi.cpp @@ -0,0 +1,182 @@ +// Configuration defines +#define _WIN32_DCOM +#define WIL_ENABLE_EXCEPTIONS + +#include + +#include + +// C++/WinRT includes +#include + +#include + +#include +#include + +struct WMI +{ + winrt::impl::com_ref locator; + winrt::com_ptr services; + + std::vector loads; +}; + +extern "C" +{ + WMI* NewWMIService() + { + winrt::init_apartment(); + + WMI* wmi = new WMI{}; + + wmi->locator = winrt::create_instance(CLSID_WbemLocator); + winrt::check_hresult(wmi->locator->ConnectServer( + wil::make_bstr(LR"(ROOT\CIMV2)").get(), + nullptr, nullptr, + 0, 0, 0, 0, + wmi->services.put()) + ); + + winrt::check_hresult(CoSetProxyBlanket( + wmi->services.get(), + RPC_C_AUTHN_WINNT, + RPC_C_AUTHZ_NONE, + nullptr, + RPC_C_AUTHN_LEVEL_CALL, + RPC_C_IMP_LEVEL_IMPERSONATE, + nullptr, + EOAC_NONE) + ); + + wmi->loads.resize(std::thread::hardware_concurrency()); + + return wmi; + } + + int WMIQueryProcessorTime(WMI* wmi, int** loads, size_t* count) + { + winrt::com_ptr enumerator; + winrt::check_hresult(wmi->services->ExecQuery( + L"WQL", + L"SELECT PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name <> '_Total'", + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + nullptr, + enumerator.put()) + ); + + for (size_t i = 0 ; i < wmi->loads.size() ; ++i) + { + winrt::com_ptr class_object; + ULONG ret; + winrt::check_hresult(enumerator->Next( + WBEM_INFINITE, + 1, + class_object.put(), + &ret) + ); + + if (ret == 0) { break; } + + wil::unique_variant percent; + winrt::check_hresult(class_object->Get( L"PercentProcessorTime", 0, percent.addressof(), nullptr, nullptr)); + + wmi->loads.at(i) = std::stoi(percent.bstrVal); + + *loads = wmi->loads.data(); + *count = wmi->loads.size(); + } + + return 0; + } + + void CloseWMIService(WMI* wmi) + { + delete wmi; + } +} +/* +int main() +{ + try + { + winrt::init_apartment(); + + auto locator = winrt::create_instance(CLSID_WbemLocator); + winrt::com_ptr services; + winrt::check_hresult(locator->ConnectServer( + wil::make_bstr(LR"(ROOT\CIMV2)").get(), + nullptr, nullptr, + 0, 0, 0, 0, + services.put()) + ); + + winrt::check_hresult(CoSetProxyBlanket( + services.get(), + RPC_C_AUTHN_WINNT, + RPC_C_AUTHZ_NONE, + nullptr, + RPC_C_AUTHN_LEVEL_CALL, + RPC_C_IMP_LEVEL_IMPERSONATE, + nullptr, + EOAC_NONE) + ); + + std::vector loads(std::thread::hardware_concurrency()); + + for(int I = 0 ; I < 10 ; ++I) + { + + auto refresher = winrt::create_instance(CLSID_WbemRefresher); + winrt::com_ptr config; + winrt::check_hresult(refresher->QueryInterface(config.put())); + + winrt::com_ptr enumerator; + winrt::check_hresult(services->ExecQuery( + L"WQL", + L"SELECT PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name <> '_Total'", + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + nullptr, + enumerator.put()) + ); + + //while (enumerator) + for (size_t i = 0 ; i < loads.size() ; ++i) + { + winrt::com_ptr class_object; + ULONG ret; + winrt::check_hresult(enumerator->Next( + WBEM_INFINITE, + 1, + class_object.put(), + &ret) + ); + + if (ret == 0) { break; } + + wil::unique_variant percent; + winrt::check_hresult(class_object->Get( L"PercentProcessorTime", 0, percent.addressof(), nullptr, nullptr)); + + loads.at(i) = std::stoi(percent.bstrVal); + } + + for(auto& load : loads) std::cout << load << "\n"; + std::cout << std::endl; + + std::this_thread::sleep_for(std::chrono::milliseconds{500}); + } + } + catch(winrt::hresult_error& err) + { + std::wcerr << err.message().c_str() << " (" << err.code() << ")" << std::endl; + std::exit(err.code()); + } + catch(std::exception& err) + { + std::cerr << err.what() << std::endl; + std::exit(-1); + } + + return 0; +} +*/ diff --git a/wmi.h b/wmi.h new file mode 100644 index 0000000..2b5f778 --- /dev/null +++ b/wmi.h @@ -0,0 +1,17 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct WMI WMI; + +WMI* NewWMIService(); + +int WMIQueryProcessorTime(WMI* wmi, int** loads, size_t* count); + +void CloseWMIService(WMI* wmi); + +#ifdef __cplusplus +} +#endif From 6c59603b95fd04557d654c123db2afcc0f0ba290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Ferenc=20Nagy-Egri?= Date: Sat, 14 Aug 2021 16:13:50 +0200 Subject: [PATCH 2/7] Remove commented code --- wmi.cpp | 85 --------------------------------------------------------- 1 file changed, 85 deletions(-) diff --git a/wmi.cpp b/wmi.cpp index 66439ff..ea336c8 100644 --- a/wmi.cpp +++ b/wmi.cpp @@ -95,88 +95,3 @@ extern "C" delete wmi; } } -/* -int main() -{ - try - { - winrt::init_apartment(); - - auto locator = winrt::create_instance(CLSID_WbemLocator); - winrt::com_ptr services; - winrt::check_hresult(locator->ConnectServer( - wil::make_bstr(LR"(ROOT\CIMV2)").get(), - nullptr, nullptr, - 0, 0, 0, 0, - services.put()) - ); - - winrt::check_hresult(CoSetProxyBlanket( - services.get(), - RPC_C_AUTHN_WINNT, - RPC_C_AUTHZ_NONE, - nullptr, - RPC_C_AUTHN_LEVEL_CALL, - RPC_C_IMP_LEVEL_IMPERSONATE, - nullptr, - EOAC_NONE) - ); - - std::vector loads(std::thread::hardware_concurrency()); - - for(int I = 0 ; I < 10 ; ++I) - { - - auto refresher = winrt::create_instance(CLSID_WbemRefresher); - winrt::com_ptr config; - winrt::check_hresult(refresher->QueryInterface(config.put())); - - winrt::com_ptr enumerator; - winrt::check_hresult(services->ExecQuery( - L"WQL", - L"SELECT PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name <> '_Total'", - WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, - nullptr, - enumerator.put()) - ); - - //while (enumerator) - for (size_t i = 0 ; i < loads.size() ; ++i) - { - winrt::com_ptr class_object; - ULONG ret; - winrt::check_hresult(enumerator->Next( - WBEM_INFINITE, - 1, - class_object.put(), - &ret) - ); - - if (ret == 0) { break; } - - wil::unique_variant percent; - winrt::check_hresult(class_object->Get( L"PercentProcessorTime", 0, percent.addressof(), nullptr, nullptr)); - - loads.at(i) = std::stoi(percent.bstrVal); - } - - for(auto& load : loads) std::cout << load << "\n"; - std::cout << std::endl; - - std::this_thread::sleep_for(std::chrono::milliseconds{500}); - } - } - catch(winrt::hresult_error& err) - { - std::wcerr << err.message().c_str() << " (" << err.code() << ")" << std::endl; - std::exit(err.code()); - } - catch(std::exception& err) - { - std::cerr << err.what() << std::endl; - std::exit(-1); - } - - return 0; -} -*/ From 2bc3b2ae9496412bb92bd6cada525d99d2ab30cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Ferenc=20Nagy-Egri?= Date: Sat, 14 Aug 2021 16:14:30 +0200 Subject: [PATCH 3/7] New CLI test for refresher object --- CMakeLists.txt | 21 ++++++ main.cpp | 188 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fcc802d..65a4800 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,3 +60,24 @@ target_compile_features(wmi target_compile_options(wmi PRIVATE /permissive ) + +add_executable(test + main.cpp +) + +target_link_libraries(test + PRIVATE + WindowsApp + wbemuuid + WIL::WIL +) + +target_compile_features(test + PRIVATE + cxx_std_17 +) + +# Temporary fix for C++/WinRT bug +target_compile_options(test + PRIVATE /permissive +) diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..79a9ad9 --- /dev/null +++ b/main.cpp @@ -0,0 +1,188 @@ +// Configuration defines +#define _WIN32_DCOM +#define WIL_ENABLE_EXCEPTIONS + +#include + +#include + +// C++/WinRT includes +#include + +#include + +#include +#include + +int main() +{ + try + { + winrt::init_apartment(); + + auto locator = winrt::create_instance(CLSID_WbemLocator); + winrt::com_ptr services; + winrt::check_hresult(locator->ConnectServer( + wil::make_bstr(LR"(ROOT\CIMV2)").get(), + nullptr, nullptr, + 0, 0, 0, 0, + services.put())); + + winrt::check_hresult(CoSetProxyBlanket( + services.get(), + RPC_C_AUTHN_WINNT, + RPC_C_AUTHZ_NONE, + nullptr, + RPC_C_AUTHN_LEVEL_CALL, + RPC_C_IMP_LEVEL_IMPERSONATE, + nullptr, + EOAC_NONE)); + + //std::vector loads(std::thread::hardware_concurrency()); + + auto refresher = winrt::create_instance(CLSID_WbemRefresher); + winrt::com_ptr config; + winrt::check_hresult(refresher->QueryInterface(config.put())); + + winrt::com_ptr enumerator; + long id; + winrt::check_hresult(config->AddEnum( + services.get(), + L"Win32_PerfFormattedData_PerfOS_Processor", + 0, + nullptr, + enumerator.put(), + &id)); + + // Obtain queried object count (using empty buffer for result storage) + winrt::check_hresult(refresher->Refresh(0L)); + ULONG logical_core_count = [&]() // IILE + { + ULONG count; + auto hresult = enumerator->GetObjects( + 0L, + 0, + nullptr, + &count + ); + if (hresult != WBEM_E_BUFFER_TOO_SMALL) + throw std::runtime_error{"Expecting WBEM_E_BUFFER_TOO_SMALL obtaining object count, got something else."}; + + return count; + }(); + + // Obtain and remember property handles + CIMTYPE percent_processor_time_handle = [&]() // IILE + { + std::vector> enum_accessors(logical_core_count); + ULONG count; + winrt::check_hresult(enumerator->GetObjects( + 0L, + logical_core_count, + reinterpret_cast(enum_accessors.data()), + &count)); + + //if (hresult != WBEM_E_BUFFER_TOO_SMALL) + // throw std::runtime_error{"Expecting hresult == WBEM_E_BUFFER_TOO_SMALL and count == 1 while obtaining PercentProcessorTime property handle."}; + + CIMTYPE handle, type; + winrt::check_hresult(enum_accessors[0]->GetPropertyHandle( + L"PercentProcessorTime", + &type, + &handle)); + + return handle; + }(); + + std::vector> enum_accessors(logical_core_count); + //std::wstring percent_processor_time_string(4, '\0'); + std::uint64_t percent_processor_time; + for(int I = 0 ; I < 10 ; ++I) + { + winrt::check_hresult(refresher->Refresh(0L)); + + ULONG count; + // Assumes that the layout of winrt::com_ptr is the same as the stored winrt::impl::abi_t + winrt::check_hresult(enumerator->GetObjects( + 0L, + static_cast(enum_accessors.size()), + reinterpret_cast(enum_accessors.data()), + &count)); + + for (auto& enum_access : enum_accessors) + { + BSTR* type_name = nullptr; + CIMTYPE prop_type; + winrt::check_hresult(enum_access->GetPropertyInfoByHandle( + percent_processor_time_handle, + type_name, + &prop_type + )); + + long bytes_read; + winrt::check_hresult(enum_access->ReadPropertyValue( + percent_processor_time_handle, + sizeof(std::uint64_t), + &bytes_read, + reinterpret_cast(&percent_processor_time))); + + std::cout << percent_processor_time << std::endl; + + //wil::unique_variant percent; + //winrt::check_hresult(enum_access->Get( L"PercentProcessorTime", 0, percent.addressof(), nullptr, nullptr)); + //std::cout << std::stoi(percent.bstrVal) << std::endl; + + } + + std::cout << std::endl; + std::this_thread::sleep_for(std::chrono::seconds{1}); + } +/* + winrt::com_ptr enumerator; + winrt::check_hresult(services->ExecQuery( + L"WQL", + L"SELECT PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name <> '_Total'", + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + nullptr, + enumerator.put()) + ); + + //while (enumerator) + for (size_t i = 0 ; i < loads.size() ; ++i) + { + winrt::com_ptr class_object; + ULONG ret; + winrt::check_hresult(enumerator->Next( + WBEM_INFINITE, + 1, + class_object.put(), + &ret) + ); + + if (ret == 0) { break; } + + wil::unique_variant percent; + winrt::check_hresult(class_object->Get( L"PercentProcessorTime", 0, percent.addressof(), nullptr, nullptr)); + + loads.at(i) = std::stoi(percent.bstrVal); + } + + for(auto& load : loads) std::cout << load << "\n"; + std::cout << std::endl; + + std::this_thread::sleep_for(std::chrono::milliseconds{500}); +*/ + } + catch(winrt::hresult_error& err) + { + std::wcerr << err.message().c_str() << " (" << err.code() << ")" << std::endl; + std::exit(err.code()); + } + catch(std::exception& err) + { + std::cerr << err.what() << std::endl; + std::exit(-1); + } + + return 0; +} \ No newline at end of file From caa0fc11091eeb4951ab3811bdc6efcff1e150ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Ferenc=20Nagy-Egri?= Date: Sat, 14 Aug 2021 16:15:24 +0200 Subject: [PATCH 4/7] Start htop-style percent bar drawing --- ntop.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/ntop.c b/ntop.c index 9b0798c..d249fb9 100644 --- a/ntop.c +++ b/ntop.c @@ -44,8 +44,6 @@ static int Width; static int Height; static int OldWidth; static int OldHeight; -static int SizeX; -static int SizeY; static const int ProcessWindowPosY = 6; static DWORD ProcessWindowHeight; static DWORD VisibleProcessCount; @@ -811,9 +809,6 @@ static BOOL PollConsoleInfo(void) return TRUE; } - SizeX = (int)Csbi.dwSize.X; - SizeY = (int)Csbi.dwSize.Y; - if(SavedAttributes == 0) SavedAttributes = Csbi.wAttributes; @@ -994,6 +989,49 @@ static int DrawPercentageBar(TCHAR *Name, double Percentage, WORD Color) return CharsWritten; } +static int LogicalCoreBardWidth; + +// Used to calculate the number of bars that should be drawn. +// NOTE: This may not be the maximum of numbers to be drawn, as +// the percentage indicator overlays on top of the bars. +static int CalculateLogicalCoreBarWidth(const int ConsoleWidth) +{ + // ConsoleWidth - Left&Right Margin - BarCount * (CoreNumLabel + []) + return ConsoleWidth - 4 - 4*(3 + 2); +} + +static int LogicalCoreCount; +static int* LogicalCoreLoads; + +static int DrawLogicalCoresPercentageBars() +{/* + int CharsWritten = 0; + + SetColor(Config.FGHighlightColor); + CharsWritten += ConPrintf(_T(" %s"), Name); + SetColor(Config.FGColor); + ConPutc('['); + CharsWritten++; + + int Bars = (int)((double)BAR_WIDTH * Percentage); + SetColor(Color); + for(int i = 0; i < Bars; i++) { + ConPutc('|'); + } + CharsWritten+= Bars; + SetColor(Config.FGColor); + for(int i = 0; i < BAR_WIDTH - Bars; i++) { + ConPutc(' '); + } + CharsWritten += BAR_WIDTH - Bars; + SetColor(Config.BGColor); + CharsWritten += ConPrintf(_T("%04.1f%%"), 100.0 * Percentage); + SetColor(Config.FGColor); + ConPutc(']'); + CharsWritten++; + return CharsWritten; +*/} + static void RestoreConsole(void) { SetConsoleActiveScreenBuffer(OldConsoleHandle); From cf66cb8e73023b1c77a9a9ef124112ad007175b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Ferenc=20Nagy-Egri?= Date: Sat, 14 Aug 2021 16:48:47 +0200 Subject: [PATCH 5/7] Test code cleanup --- CMakeLists.txt | 5 ----- main.cpp | 59 +++----------------------------------------------- 2 files changed, 3 insertions(+), 61 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 65a4800..406a4f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,8 +76,3 @@ target_compile_features(test PRIVATE cxx_std_17 ) - -# Temporary fix for C++/WinRT bug -target_compile_options(test - PRIVATE /permissive -) diff --git a/main.cpp b/main.cpp index 79a9ad9..fda1476 100644 --- a/main.cpp +++ b/main.cpp @@ -38,8 +38,6 @@ int main() nullptr, EOAC_NONE)); - //std::vector loads(std::thread::hardware_concurrency()); - auto refresher = winrt::create_instance(CLSID_WbemRefresher); winrt::com_ptr config; winrt::check_hresult(refresher->QueryInterface(config.put())); @@ -82,9 +80,6 @@ int main() reinterpret_cast(enum_accessors.data()), &count)); - //if (hresult != WBEM_E_BUFFER_TOO_SMALL) - // throw std::runtime_error{"Expecting hresult == WBEM_E_BUFFER_TOO_SMALL and count == 1 while obtaining PercentProcessorTime property handle."}; - CIMTYPE handle, type; winrt::check_hresult(enum_accessors[0]->GetPropertyHandle( L"PercentProcessorTime", @@ -95,7 +90,6 @@ int main() }(); std::vector> enum_accessors(logical_core_count); - //std::wstring percent_processor_time_string(4, '\0'); std::uint64_t percent_processor_time; for(int I = 0 ; I < 10 ; ++I) { @@ -109,69 +103,22 @@ int main() reinterpret_cast(enum_accessors.data()), &count)); - for (auto& enum_access : enum_accessors) + // Loop over core loads. (Last entry seems to be an avarage of all cores.) + for (size_t i = 0 ; i < enum_accessors.size() - 1 ; ++i) { - BSTR* type_name = nullptr; - CIMTYPE prop_type; - winrt::check_hresult(enum_access->GetPropertyInfoByHandle( - percent_processor_time_handle, - type_name, - &prop_type - )); - long bytes_read; - winrt::check_hresult(enum_access->ReadPropertyValue( + winrt::check_hresult(enum_accessors[i]->ReadPropertyValue( percent_processor_time_handle, sizeof(std::uint64_t), &bytes_read, reinterpret_cast(&percent_processor_time))); std::cout << percent_processor_time << std::endl; - - //wil::unique_variant percent; - //winrt::check_hresult(enum_access->Get( L"PercentProcessorTime", 0, percent.addressof(), nullptr, nullptr)); - //std::cout << std::stoi(percent.bstrVal) << std::endl; - } std::cout << std::endl; std::this_thread::sleep_for(std::chrono::seconds{1}); } -/* - winrt::com_ptr enumerator; - winrt::check_hresult(services->ExecQuery( - L"WQL", - L"SELECT PercentProcessorTime FROM Win32_PerfFormattedData_PerfOS_Processor WHERE Name <> '_Total'", - WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, - nullptr, - enumerator.put()) - ); - - //while (enumerator) - for (size_t i = 0 ; i < loads.size() ; ++i) - { - winrt::com_ptr class_object; - ULONG ret; - winrt::check_hresult(enumerator->Next( - WBEM_INFINITE, - 1, - class_object.put(), - &ret) - ); - - if (ret == 0) { break; } - - wil::unique_variant percent; - winrt::check_hresult(class_object->Get( L"PercentProcessorTime", 0, percent.addressof(), nullptr, nullptr)); - - loads.at(i) = std::stoi(percent.bstrVal); - } - - for(auto& load : loads) std::cout << load << "\n"; - std::cout << std::endl; - - std::this_thread::sleep_for(std::chrono::milliseconds{500}); -*/ } catch(winrt::hresult_error& err) { From a695c4b3c6d2ed56df03a99abac73725e5effe38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Ferenc=20Nagy-Egri?= Date: Sat, 14 Aug 2021 17:17:11 +0200 Subject: [PATCH 6/7] Read User/Privileged/Total CPU time --- main.cpp | 68 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/main.cpp b/main.cpp index fda1476..0499939 100644 --- a/main.cpp +++ b/main.cpp @@ -54,7 +54,7 @@ int main() // Obtain queried object count (using empty buffer for result storage) winrt::check_hresult(refresher->Refresh(0L)); - ULONG logical_core_count = [&]() // IILE + ULONG processor_enum_count = [&]() // IILE { ULONG count; auto hresult = enumerator->GetObjects( @@ -70,27 +70,29 @@ int main() }(); // Obtain and remember property handles - CIMTYPE percent_processor_time_handle = [&]() // IILE - { - std::vector> enum_accessors(logical_core_count); - ULONG count; - winrt::check_hresult(enumerator->GetObjects( - 0L, - logical_core_count, - reinterpret_cast(enum_accessors.data()), - &count)); + auto obtain_property_handle = [&](const wchar_t* property_name) + { + std::vector> enum_accessors(processor_enum_count); + ULONG count; + winrt::check_hresult(enumerator->GetObjects( + 0L, + processor_enum_count, + reinterpret_cast(enum_accessors.data()), + &count)); - CIMTYPE handle, type; - winrt::check_hresult(enum_accessors[0]->GetPropertyHandle( - L"PercentProcessorTime", - &type, - &handle)); + CIMTYPE handle, type; + winrt::check_hresult(enum_accessors[0]->GetPropertyHandle( + property_name, + &type, + &handle)); - return handle; - }(); + return handle; + }; + CIMTYPE percent_user_time_handle = obtain_property_handle(L"PercentUserTime"), + percent_privileged_time_handle = obtain_property_handle(L"PercentPrivilegedTime"), + percent_processor_time_handle = obtain_property_handle(L"PercentProcessorTime"); - std::vector> enum_accessors(logical_core_count); - std::uint64_t percent_processor_time; + std::vector> enum_accessors(processor_enum_count); for(int I = 0 ; I < 10 ; ++I) { winrt::check_hresult(refresher->Refresh(0L)); @@ -104,16 +106,26 @@ int main() &count)); // Loop over core loads. (Last entry seems to be an avarage of all cores.) - for (size_t i = 0 ; i < enum_accessors.size() - 1 ; ++i) + for (size_t i = 0 ; i < std::thread::hardware_concurrency() ; ++i) { - long bytes_read; - winrt::check_hresult(enum_accessors[i]->ReadPropertyValue( - percent_processor_time_handle, - sizeof(std::uint64_t), - &bytes_read, - reinterpret_cast(&percent_processor_time))); - - std::cout << percent_processor_time << std::endl; + auto read_uint64_t_property = [&](long handle) + { + long bytes_read; + std::uint64_t result; + winrt::check_hresult(enum_accessors[i]->ReadPropertyValue( + handle, + sizeof(std::uint64_t), + &bytes_read, + reinterpret_cast(&result))); + + return result; + }; + + std::cout << + read_uint64_t_property(percent_user_time_handle) << "\t" << + read_uint64_t_property(percent_privileged_time_handle) << "\t" << + read_uint64_t_property(percent_processor_time_handle) << "\t" << + std::endl; } std::cout << std::endl; From 3111a778d1829a175ed6b3c91426716612cea95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Ferenc=20Nagy-Egri?= Date: Sat, 14 Aug 2021 17:19:37 +0200 Subject: [PATCH 7/7] Fix property handle type --- main.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/main.cpp b/main.cpp index 0499939..9092f00 100644 --- a/main.cpp +++ b/main.cpp @@ -80,7 +80,8 @@ int main() reinterpret_cast(enum_accessors.data()), &count)); - CIMTYPE handle, type; + CIMTYPE type; + long handle; winrt::check_hresult(enum_accessors[0]->GetPropertyHandle( property_name, &type, @@ -88,9 +89,9 @@ int main() return handle; }; - CIMTYPE percent_user_time_handle = obtain_property_handle(L"PercentUserTime"), - percent_privileged_time_handle = obtain_property_handle(L"PercentPrivilegedTime"), - percent_processor_time_handle = obtain_property_handle(L"PercentProcessorTime"); + long percent_user_time_handle = obtain_property_handle(L"PercentUserTime"), + percent_privileged_time_handle = obtain_property_handle(L"PercentPrivilegedTime"), + percent_processor_time_handle = obtain_property_handle(L"PercentProcessorTime"); std::vector> enum_accessors(processor_enum_count); for(int I = 0 ; I < 10 ; ++I)