@@ -53,20 +53,109 @@ NWL_GetCpuUsage(VOID)
5353 return ret ;
5454}
5555
56+ static PSYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION
57+ GetProcessorPerfDist (size_t * pCount )
58+ {
59+ ULONG len = 0 ;
60+ NTSTATUS rc = NWL_NtQuerySystemInformation (SystemProcessorPerformanceDistribution , NULL , 0 , & len );
61+ if (len == 0 )
62+ return NULL ;
63+ PSYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION ppd = (PSYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION )malloc (len );
64+ if (!ppd )
65+ return NULL ;
66+ rc = NWL_NtQuerySystemInformation (SystemProcessorPerformanceDistribution , ppd , len , & len );
67+ if (!NT_SUCCESS (rc ))
68+ {
69+ free (ppd );
70+ return NULL ;
71+ }
72+ if (pCount )
73+ * pCount = ppd -> ProcessorCount ;
74+ return ppd ;
75+ }
76+
5677DWORD
5778NWL_GetCpuFreq (VOID )
5879{
59- DWORD ret = 0 ;
60- DWORD freq = 0 ;
6180 PDH_FMT_COUNTERVALUE value = { 0 };
62- NWL_GetRegDwordValue (HKEY_LOCAL_MACHINE , L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0" , L"~MHz" , & ret );
6381 if (NWLC -> PdhCpuBaseFreq &&
6482 NWLC -> PdhGetFormattedCounterValue (NWLC -> PdhCpuBaseFreq , PDH_FMT_LONG , NULL , & value ) == ERROR_SUCCESS )
65- freq = (DWORD )value .longValue ;
66- if (NWLC -> PdhCpuFreq &&
67- NWLC -> PdhGetFormattedCounterValue (NWLC -> PdhCpuFreq , PDH_FMT_DOUBLE , NULL , & value ) == ERROR_SUCCESS )
68- ret = (DWORD )(value .doubleValue * 0.01 * freq );
69- return ret ;
83+ {
84+ DWORD freq = (DWORD )value .longValue ;
85+ if (NWLC -> PdhCpuFreq &&
86+ NWLC -> PdhGetFormattedCounterValue (NWLC -> PdhCpuFreq , PDH_FMT_DOUBLE , NULL , & value ) == ERROR_SUCCESS )
87+ return (DWORD )(value .doubleValue * 0.01 * freq );
88+ }
89+
90+ static PSYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION saved_ppd = NULL ;
91+ PSYSTEM_PROCESSOR_PERFORMANCE_DISTRIBUTION cur_ppd = NULL ;
92+
93+ size_t cpu_count = 0 ;
94+ PPROCESSOR_POWER_INFORMATION ppi = NWL_NtPowerInformation (& cpu_count );
95+ if (cpu_count == 0 || ppi == NULL )
96+ goto fail ;
97+
98+ if (NWLC -> NwOsInfo .dwMajorVersion < 10 )
99+ {
100+ ULONG sum = 0 ;
101+ for (size_t i = 0 ; i < cpu_count ; i ++ )
102+ sum += ppi [i ].CurrentMhz ;
103+ free (ppi );
104+ return (DWORD ) (sum / cpu_count );
105+ }
106+
107+ if (!saved_ppd )
108+ saved_ppd = GetProcessorPerfDist (NULL );
109+ if (!saved_ppd )
110+ goto fail ;
111+ cur_ppd = GetProcessorPerfDist (NULL );
112+ if (!cur_ppd )
113+ goto fail ;
114+ if (cur_ppd -> ProcessorCount != saved_ppd -> ProcessorCount ||
115+ cur_ppd -> ProcessorCount < cpu_count )
116+ goto fail ;
117+
118+ ULONGLONG total_hits_delta = 0 ;
119+ ULONGLONG total_freq_contrib = 0 ;
120+ for (size_t i = 0 ; i < cur_ppd -> ProcessorCount ; i ++ )
121+ {
122+ PSYSTEM_PROCESSOR_PERFORMANCE_STATE_DISTRIBUTION cur_state =
123+ (PSYSTEM_PROCESSOR_PERFORMANCE_STATE_DISTRIBUTION )((BYTE * )cur_ppd + cur_ppd -> Offsets [i ]);
124+ PSYSTEM_PROCESSOR_PERFORMANCE_STATE_DISTRIBUTION saved_state =
125+ (PSYSTEM_PROCESSOR_PERFORMANCE_STATE_DISTRIBUTION )((BYTE * )saved_ppd + saved_ppd -> Offsets [i ]);
126+ if (cur_state -> StateCount != saved_state -> StateCount )
127+ continue ;
128+ ULONG max_mhz = ppi [i ].MaxMhz ;
129+ if (max_mhz == 0 )
130+ max_mhz = ppi [0 ].MaxMhz ;
131+ for (ULONG j = 0 ; j < cur_state -> StateCount ; j ++ )
132+ {
133+ ULONGLONG hits_delta = cur_state -> States [j ].Hits - saved_state -> States [j ].Hits ;
134+ total_hits_delta += hits_delta ;
135+ total_freq_contrib += hits_delta * cur_state -> States [j ].PercentFrequency * max_mhz ;
136+ }
137+ }
138+
139+ free (ppi );
140+ free (saved_ppd );
141+ saved_ppd = cur_ppd ;
142+
143+ if (total_hits_delta == 0 )
144+ return 0 ;
145+ return (DWORD )(total_freq_contrib / total_hits_delta / 100 );
146+
147+ fail :
148+ if (saved_ppd )
149+ {
150+ free (saved_ppd );
151+ saved_ppd = NULL ;
152+ }
153+ if (cur_ppd )
154+ free (cur_ppd );
155+
156+ DWORD reg_freq = 0 ;
157+ NWL_GetRegDwordValue (HKEY_LOCAL_MACHINE , L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0" , L"~MHz" , & reg_freq );
158+ return reg_freq ;
70159}
71160
72161static LPCSTR
0 commit comments