Skip to content

Commit

Permalink
新增Lite版显示频率的功能,修正ARM64EC显示CPU频率不正常的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
zhongyang219 committed Jan 20, 2025
1 parent 04f4bb3 commit 655bc9c
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 110 deletions.
177 changes: 119 additions & 58 deletions TrafficMonitor/CPUUsage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,82 +2,143 @@
#include "CPUUsage.h"
#include "Common.h"
#include "TrafficMonitor.h"
#include <powerbase.h>
#include <sysinfoapi.h>

void CCPUUsage::SetUseCPUTimes(bool use_get_system_times)
{
if (m_use_get_system_times != use_get_system_times)
{
m_use_get_system_times = use_get_system_times;
m_first_get_CPU_utility = true;
}
if (m_use_get_system_times != use_get_system_times)
{
m_use_get_system_times = use_get_system_times;
m_first_get_CPU_utility = true;
}
}

int CCPUUsage::GetCPUUsage()
{
if (m_use_get_system_times)
return GetCPUUsageByGetSystemTimes();
else
return GetCPUUsageByPdh();
if (m_use_get_system_times)
return GetCPUUsageByGetSystemTimes();
else
return GetCPUUsageByPdh();
}

int CCPUUsage::GetCPUUsageByGetSystemTimes()
{
int cpu_usage{};
FILETIME idleTime;
FILETIME kernelTime;
FILETIME userTime;
GetSystemTimes(&idleTime, &kernelTime, &userTime);
int cpu_usage{};
FILETIME idleTime;
FILETIME kernelTime;
FILETIME userTime;
GetSystemTimes(&idleTime, &kernelTime, &userTime);

__int64 idle = CCommon::CompareFileTime2(m_preidleTime, idleTime);
__int64 kernel = CCommon::CompareFileTime2(m_prekernelTime, kernelTime);
__int64 user = CCommon::CompareFileTime2(m_preuserTime, userTime);
__int64 idle = CCommon::CompareFileTime2(m_preidleTime, idleTime);
__int64 kernel = CCommon::CompareFileTime2(m_prekernelTime, kernelTime);
__int64 user = CCommon::CompareFileTime2(m_preuserTime, userTime);

if (kernel + user == 0)
{
cpu_usage = 0;
}
else
{
//(总的时间-空闲时间)/总的时间=占用cpu的时间就是使用率
cpu_usage = static_cast<int>(abs((kernel + user - idle) * 100 / (kernel + user)));
}
m_preidleTime = idleTime;
m_prekernelTime = kernelTime;
m_preuserTime = userTime;
if (kernel + user == 0)
{
cpu_usage = 0;
}
else
{
//(总的时间-空闲时间)/总的时间=占用cpu的时间就是使用率
cpu_usage = static_cast<int>(abs((kernel + user - idle) * 100 / (kernel + user)));
}
m_preidleTime = idleTime;
m_prekernelTime = kernelTime;
m_preuserTime = userTime;

return cpu_usage;
return cpu_usage;
}

int CCPUUsage::GetCPUUsageByPdh()
{
int cpu_usage{};
HQUERY hQuery;
HCOUNTER hCounter;
DWORD counterType;
PDH_RAW_COUNTER rawData;
int cpu_usage{};
HQUERY hQuery;
HCOUNTER hCounter;
DWORD counterType;
PDH_RAW_COUNTER rawData;

PdhOpenQuery(NULL, 0, &hQuery);//开始查询
const wchar_t* query_str{};
if (theApp.m_win_version.GetMajorVersion() >= 10)
query_str = L"\\Processor Information(_Total)\\% Processor Utility";
else
query_str = L"\\Processor Information(_Total)\\% Processor Time";
PdhAddCounter(hQuery, query_str, NULL, &hCounter);
PdhCollectQueryData(hQuery);
PdhGetRawCounterValue(hCounter, &counterType, &rawData);
PdhOpenQuery(NULL, 0, &hQuery);//开始查询
const wchar_t* query_str{};
if (theApp.m_win_version.GetMajorVersion() >= 10)
query_str = L"\\Processor Information(_Total)\\% Processor Utility";
else
query_str = L"\\Processor Information(_Total)\\% Processor Time";
PdhAddCounter(hQuery, query_str, NULL, &hCounter);
PdhCollectQueryData(hQuery);
PdhGetRawCounterValue(hCounter, &counterType, &rawData);

if (m_first_get_CPU_utility) {//需要获得两次数据才能计算CPU使用率
cpu_usage = 0;
m_first_get_CPU_utility = false;
}
else {
PDH_FMT_COUNTERVALUE fmtValue;
PdhCalculateCounterFromRawValue(hCounter, PDH_FMT_DOUBLE, &rawData, &m_last_rawData, &fmtValue);//计算使用率
cpu_usage = fmtValue.doubleValue;//传出数据
if (cpu_usage > 100)
cpu_usage = 100;
}
m_last_rawData = rawData;//保存上一次数据
PdhCloseQuery(hQuery);//关闭查询
return cpu_usage;
if (m_first_get_CPU_utility) {//需要获得两次数据才能计算CPU使用率
cpu_usage = 0;
m_first_get_CPU_utility = false;
}
else {
PDH_FMT_COUNTERVALUE fmtValue;
PdhCalculateCounterFromRawValue(hCounter, PDH_FMT_DOUBLE, &rawData, &m_last_rawData, &fmtValue);//计算使用率
cpu_usage = fmtValue.doubleValue;//传出数据
if (cpu_usage > 100)
cpu_usage = 100;
}
m_last_rawData = rawData;//保存上一次数据
PdhCloseQuery(hQuery);//关闭查询
return cpu_usage;
}

///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////

typedef struct _PROCESSOR_POWER_INFORMATION {
ULONG Number;
ULONG MaxMhz;
ULONG CurrentMhz;
ULONG MhzLimit;
ULONG MaxIdleState;
ULONG CurrentIdleState;
} PROCESSOR_POWER_INFORMATION, * PPROCESSOR_POWER_INFORMATION;

CCpuFreq::CCpuFreq()
{
SYSTEM_INFO si;
GetSystemInfo(&si);
auto ppInfo = std::vector<PROCESSOR_POWER_INFORMATION>(si.dwNumberOfProcessors);
auto status = CallNtPowerInformation(POWER_INFORMATION_LEVEL::ProcessorInformation,
NULL, 0, &ppInfo[0], sizeof(PROCESSOR_POWER_INFORMATION) * ppInfo.size());
for (size_t i = 0; i < ppInfo.size(); i++)
{
max_cpu_freq = max(max_cpu_freq, ppInfo[i].MaxMhz / 1000.f);
}

}

float CCpuFreq::GetCpuFreq()
{
float freq{};
HQUERY query;
PDH_STATUS status = PdhOpenQuery(NULL, NULL, &query);
if (status != ERROR_SUCCESS)
{
freq = 0.1;
return true;
}
HCOUNTER counter;
status = PdhAddCounterA(query, LPCSTR("\\Processor Information(_Total)\\% Processor Performance"), NULL, &counter);
if (status != ERROR_SUCCESS)
{
freq = 0.2;
return true;
}
PdhCollectQueryData(query);
Sleep(200);
PdhCollectQueryData(query);
PDH_FMT_COUNTERVALUE pdhValue;
DWORD dwValue;
status = PdhGetFormattedCounterValue(counter, PDH_FMT_DOUBLE, &dwValue, &pdhValue);
if (status != ERROR_SUCCESS)
{
freq = 0.3;
return true;
}
PdhCloseQuery(query);
freq = pdhValue.doubleValue / 100 * max_cpu_freq;
return freq;
}
38 changes: 23 additions & 15 deletions TrafficMonitor/CPUUsage.h
Original file line number Diff line number Diff line change
@@ -1,33 +1,41 @@
#pragma once
#include <Pdh.h>
#include <PdhMsg.h>
#pragma comment(lib,"pdh.lib")

class CCPUUsage
{
public:
CCPUUsage()
{}
CCPUUsage()
{}

~CCPUUsage()
{}
~CCPUUsage()
{}

void SetUseCPUTimes(bool use_get_system_times); //设置获取CPU利用率的方式,是通过GetSystemTimes还是Pdh
int GetCPUUsage();
void SetUseCPUTimes(bool use_get_system_times); //设置获取CPU利用率的方式,是通过GetSystemTimes还是Pdh
int GetCPUUsage();

private:
int GetCPUUsageByGetSystemTimes();
int GetCPUUsageByPdh();
int GetCPUUsageByGetSystemTimes();
int GetCPUUsageByPdh();

private:
bool m_use_get_system_times{ true }; //是否使用GetSysTime这个API来获取CPU利用率
bool m_use_get_system_times{ true }; //是否使用GetSysTime这个API来获取CPU利用率

PDH_RAW_COUNTER m_last_rawData;//保存计算CPU使用率的上一次数据
bool m_first_get_CPU_utility{ true };
PDH_RAW_COUNTER m_last_rawData{};//保存计算CPU使用率的上一次数据
bool m_first_get_CPU_utility{ true };

FILETIME m_preidleTime{};
FILETIME m_prekernelTime{};
FILETIME m_preuserTime{};
FILETIME m_preidleTime{};
FILETIME m_prekernelTime{};
FILETIME m_preuserTime{};

};

class CCpuFreq
{
public:
CCpuFreq();
float GetCpuFreq();

private:
float max_cpu_freq = 0;
};
1 change: 0 additions & 1 deletion TrafficMonitor/GeneralSettingsDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ void CGeneralSettingsDlg::CheckTaskbarDisplayItem()
if (!theApp.m_general_data.IsHardwareEnable(HI_CPU))
{
theApp.m_taskbar_data.m_tbar_display_item &= ~TDI_CPU_TEMP;
theApp.m_taskbar_data.m_tbar_display_item &= ~TDI_CPU_FREQ;
}
if (!theApp.m_general_data.IsHardwareEnable(HI_GPU))
{
Expand Down
11 changes: 6 additions & 5 deletions TrafficMonitor/TaskBarDlg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,12 @@ CString CTaskBarDlg::GetMouseTipsInfo()
CCommon::KBytesToString(theApp.m_total_memory));
tip_info += temp;
}
if (!IsItemShow(TDI_CPU_FREQ) && theApp.m_cpu_freq > 0)
{
temp.Format(_T("\r\n%s: %s"), CCommon::LoadText(IDS_CPU_FREQ), CCommon::FreqToString(theApp.m_cpu_freq, theApp.m_taskbar_data));
tip_info += temp;
}

#ifndef WITHOUT_TEMPERATURE
CTrafficMonitorDlg* pMainWnd = dynamic_cast<CTrafficMonitorDlg*>(theApp.m_pMainWnd);
if (pMainWnd->IsTemperatureNeeded())
Expand All @@ -941,11 +947,6 @@ CString CTaskBarDlg::GetMouseTipsInfo()
temp.Format(_T("\r\n%s: %s"), CCommon::LoadText(IDS_CPU_TEMPERATURE), CCommon::TemperatureToString(theApp.m_cpu_temperature, theApp.m_taskbar_data));
tip_info += temp;
}
if (!IsItemShow(TDI_CPU_FREQ) && theApp.m_cpu_freq > 0)
{
temp.Format(_T("\r\n%s: %s"), CCommon::LoadText(IDS_CPU_FREQ), CCommon::FreqToString(theApp.m_cpu_freq, theApp.m_taskbar_data));
tip_info += temp;
}
if (!IsItemShow(TDI_GPU_TEMP) && theApp.m_gpu_temperature > 0)
{
temp.Format(_T("\r\n%s: %s"), CCommon::LoadText(IDS_GPU_TEMPERATURE), CCommon::TemperatureToString(theApp.m_gpu_temperature, theApp.m_taskbar_data));
Expand Down
2 changes: 1 addition & 1 deletion TrafficMonitor/TaskbarItemOrderHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ bool CTaskbarItemOrderHelper::IsItemDisplayed(CommonDisplayItem item)
bool displayed = true;
if (!item.is_plugin)
{
if ((item == TDI_CPU_TEMP || item == TDI_CPU_FREQ) && !theApp.m_general_data.IsHardwareEnable(HI_CPU))
if ((item == TDI_CPU_TEMP) && !theApp.m_general_data.IsHardwareEnable(HI_CPU))
displayed = false;
if ((item == TDI_GPU_TEMP || item == TDI_GPU_USAGE) && !theApp.m_general_data.IsHardwareEnable(HI_GPU))
displayed = false;
Expand Down
4 changes: 2 additions & 2 deletions TrafficMonitor/TaskbarItemOrderHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ const std::set<DisplayItem> AllDisplayItems
{
TDI_UP, TDI_DOWN, TDI_CPU, TDI_MEMORY
#ifndef WITHOUT_TEMPERATURE
, TDI_GPU_USAGE, TDI_CPU_TEMP, TDI_GPU_TEMP, TDI_HDD_TEMP, TDI_MAIN_BOARD_TEMP, TDI_HDD_USAGE,TDI_CPU_FREQ
, TDI_GPU_USAGE, TDI_CPU_TEMP, TDI_GPU_TEMP, TDI_HDD_TEMP, TDI_MAIN_BOARD_TEMP, TDI_HDD_USAGE
#endif
, TDI_TOTAL_SPEED, TDI_TODAY_TRAFFIC
,TDI_CPU_FREQ, TDI_TOTAL_SPEED, TDI_TODAY_TRAFFIC
};


Expand Down
Loading

0 comments on commit 655bc9c

Please sign in to comment.