Windows Use vector for performance counter data allocation

This commit is contained in:
Megamouse 2023-05-18 00:10:49 +02:00
parent f8009451a9
commit 4fd21f7764
2 changed files with 31 additions and 18 deletions

View File

@ -2,7 +2,9 @@
#include "util/cpu_stats.hpp"
#include "util/sysinfo.hpp"
#include "util/logs.hpp"
#include "util/asm.hpp"
#include "Utilities/StrUtil.h"
#include <algorithm>
#ifdef _WIN32
@ -80,6 +82,20 @@ namespace utils
#endif
}
cpu_stats::~cpu_stats()
{
#ifdef _WIN32
if (m_cpu_query)
{
PDH_STATUS status = PdhCloseQuery(m_cpu_query);
if (ERROR_SUCCESS != status)
{
perf_log.error("Failed to close cpu query of per core cpu usage: %s", pdh_error(status));
}
}
#endif
}
void cpu_stats::init_cpu_query()
{
#ifdef _WIN32
@ -139,37 +155,35 @@ namespace utils
return;
}
PDH_FMT_COUNTERVALUE counterVal{};
DWORD dwBufferSize = 0; // Size of the pItems buffer
DWORD dwItemCount = 0; // Number of items in the pItems buffer
PDH_FMT_COUNTERVALUE_ITEM *pItems = NULL; // Array of PDH_FMT_COUNTERVALUE_ITEM structures
DWORD dwBufferSize = 0; // Size of the items buffer
DWORD dwItemCount = 0; // Number of items in the items buffer
status = PdhGetFormattedCounterArray(m_cpu_cores, PDH_FMT_DOUBLE, &dwBufferSize, &dwItemCount, pItems);
status = PdhGetFormattedCounterArray(m_cpu_cores, PDH_FMT_DOUBLE, &dwBufferSize, &dwItemCount, nullptr);
if (PDH_MORE_DATA == status)
{
pItems = (PDH_FMT_COUNTERVALUE_ITEM*)malloc(dwBufferSize);
if (pItems)
std::vector<PDH_FMT_COUNTERVALUE_ITEM> items(utils::aligned_div(dwBufferSize, sizeof(PDH_FMT_COUNTERVALUE_ITEM)));
if (items.size() >= dwItemCount)
{
status = PdhGetFormattedCounterArray(m_cpu_cores, PDH_FMT_DOUBLE, &dwBufferSize, &dwItemCount, pItems);
status = PdhGetFormattedCounterArray(m_cpu_cores, PDH_FMT_DOUBLE, &dwBufferSize, &dwItemCount, items.data());
if (ERROR_SUCCESS == status)
{
ensure(dwItemCount > 0);
ensure((dwItemCount - 1) == per_core_usage.size()); // Remove one for _Total
ensure(dwItemCount == per_core_usage.size() + 1); // Plus one for _Total
// Loop through the array and get the instance name and percentage.
for (DWORD i = 0; i < dwItemCount; i++)
for (usz i = 0; i < dwItemCount; i++)
{
const std::string token = wchar_to_utf8(pItems[i].szName);
const PDH_FMT_COUNTERVALUE_ITEM& item = items[i];
const std::string token = wchar_to_utf8(item.szName);
if (const std::string lower = fmt::to_lower(token); lower.find("total") != umax)
{
total_usage = pItems[i].FmtValue.doubleValue;
total_usage = item.FmtValue.doubleValue;
continue;
}
if (const auto [success, cpu_index] = string_to_number(token); success && cpu_index < dwItemCount)
{
per_core_usage[cpu_index] = pItems[i].FmtValue.doubleValue;
per_core_usage[cpu_index] = item.FmtValue.doubleValue;
}
else if (!success)
{
@ -188,10 +202,9 @@ namespace utils
}
else
{
perf_log.error("Failed to allocate buffer for per core cpu usage.");
perf_log.error("Failed to allocate buffer for per core cpu usage. (size=%d, dwItemCount=%d)", items.size(), dwItemCount);
}
}
if (pItems) free(pItems);
#elif __linux__
@ -362,8 +375,7 @@ namespace utils
entry.dwSize = sizeof(entry);
// get the first process info.
BOOL ret = true;
ret = Process32First(snapshot, &entry);
BOOL ret = Process32First(snapshot, &entry);
while (ret && entry.th32ProcessID != id)
{
ret = Process32Next(snapshot, &entry);

View File

@ -28,6 +28,7 @@ namespace utils
public:
cpu_stats();
~cpu_stats();
double get_usage();