|
2 | 2 | cpu.c
|
3 | 3 | get percentage of CPU usage
|
4 | 4 | Kazubon 2001
|
| 5 | + tapetums 2016 |
5 | 6 | ---------------------------------------------------------------------------*/
|
6 | 7 |
|
7 | 8 | #include "tcdll.h"
|
8 | 9 |
|
9 | 10 | #if TC_ENABLE_CPU
|
10 | 11 |
|
| 12 | +#include <pdh.h> |
| 13 | + |
| 14 | +#define MAX_PROCESSOR 8 |
| 15 | + |
| 16 | +// cpu usage |
| 17 | +int CPUUsage[MAX_PROCESSOR] = { 0 }; |
| 18 | + |
| 19 | +HMODULE hmodPDH = NULL; |
| 20 | +PDH_HQUERY hQuery = NULL; |
| 21 | + |
| 22 | +typedef PDH_STATUS (WINAPI* pfnPdhOpenQueryW) (LPCWSTR, DWORD_PTR, PDH_HQUERY*); |
| 23 | +typedef PDH_STATUS (WINAPI* pfnPdhAddCounterW) (PDH_HQUERY, LPCWSTR, DWORD_PTR, PDH_HCOUNTER*); |
| 24 | +typedef PDH_STATUS (WINAPI* pfnPdhCollectQueryData) (PDH_HQUERY); |
| 25 | +typedef PDH_STATUS (WINAPI* pfnPdhGetFormattedCounterValue)(PDH_HCOUNTER, DWORD, LPDWORD, PPDH_FMT_COUNTERVALUE); |
| 26 | +typedef PDH_STATUS (WINAPI* pfnPdhCloseQuery) (PDH_HQUERY); |
| 27 | +typedef PDH_STATUS (WINAPI* pfnPdhRemoveCounter) (PDH_HCOUNTER); |
| 28 | + |
| 29 | +pfnPdhOpenQueryW pPdhOpenQueryW = NULL; |
| 30 | +pfnPdhAddCounterW pPdhAddCounterW = NULL; |
| 31 | +pfnPdhCollectQueryData pPdhCollectQueryData = NULL; |
| 32 | +pfnPdhGetFormattedCounterValue pPdhGetFormattedCounterValue = NULL; |
| 33 | +pfnPdhCloseQuery pPdhCloseQuery = NULL; |
| 34 | +pfnPdhRemoveCounter pPdhRemoveCounter = NULL; |
| 35 | + |
| 36 | +PDH_HCOUNTER hTotalCPUCounter = NULL; |
| 37 | +PDH_HCOUNTER hCPUCounter[MAX_PROCESSOR] = { NULL }; |
| 38 | + |
11 | 39 | void CpuMoni_start(void)
|
12 | 40 | {
|
| 41 | + if ( hmodPDH ) |
| 42 | + { |
| 43 | + CpuMoni_end(); |
| 44 | + } |
| 45 | + |
| 46 | + hmodPDH = LoadLibraryExW(L"pdh.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 47 | + if ( hmodPDH == NULL ) |
| 48 | + { |
| 49 | + return; |
| 50 | + } |
| 51 | + |
| 52 | + pPdhOpenQueryW = (pfnPdhOpenQueryW) GetProcAddress(hmodPDH, "PdhOpenQueryW"); |
| 53 | + pPdhAddCounterW = (pfnPdhAddCounterW) GetProcAddress(hmodPDH, "PdhAddCounterW"); |
| 54 | + pPdhRemoveCounter = (pfnPdhRemoveCounter) GetProcAddress(hmodPDH, "PdhRemoveCounter"); |
| 55 | + pPdhCollectQueryData = (pfnPdhCollectQueryData) GetProcAddress(hmodPDH, "PdhCollectQueryData"); |
| 56 | + pPdhGetFormattedCounterValue = (pfnPdhGetFormattedCounterValue)GetProcAddress(hmodPDH, "PdhGetFormattedCounterValue"); |
| 57 | + pPdhCloseQuery = (pfnPdhCloseQuery) GetProcAddress(hmodPDH, "PdhCloseQuery"); |
| 58 | + |
| 59 | + if ( pPdhOpenQueryW == NULL || |
| 60 | + pPdhAddCounterW == NULL || |
| 61 | + pPdhCollectQueryData == NULL || |
| 62 | + pPdhRemoveCounter == NULL || |
| 63 | + pPdhGetFormattedCounterValue == NULL || |
| 64 | + pPdhCloseQuery == NULL ) |
| 65 | + { |
| 66 | + goto FAILURE_PDH_COUNTER_INITIALIZATION; |
| 67 | + } |
| 68 | + |
| 69 | + PDH_STATUS status; |
| 70 | + |
| 71 | + // initialize |
| 72 | + status = pPdhOpenQueryW(NULL, 0, &hQuery); |
| 73 | + if ( status != ERROR_SUCCESS ) |
| 74 | + { |
| 75 | + goto FAILURE_PDH_COUNTER_INITIALIZATION; |
| 76 | + } |
| 77 | + |
| 78 | + // create cpu counter |
| 79 | + wchar_t counterName[64]; |
| 80 | + for ( int i = 0; i < MAX_PROCESSOR; ++i ) |
| 81 | + { |
| 82 | + wsprintfW(counterName, L"\\Processor(%d)\\%% Processor Time", i); |
| 83 | + |
| 84 | + status = pPdhAddCounterW(hQuery, counterName, 0, &hCPUCounter[i]); |
| 85 | + if ( status != ERROR_SUCCESS ) |
| 86 | + { |
| 87 | + goto FAILURE_PDH_COUNTER_INITIALIZATION; |
| 88 | + } |
| 89 | + } |
| 90 | + |
| 91 | + // create total cpu usage counter |
| 92 | + status = pPdhAddCounterW(hQuery, L"\\Processor(_Total)\\% Processor Time", 0, &hTotalCPUCounter); |
| 93 | + if ( status != ERROR_SUCCESS ) |
| 94 | + { |
| 95 | + goto FAILURE_PDH_COUNTER_INITIALIZATION; |
| 96 | + } |
| 97 | + |
| 98 | + return; /* SUCCESS */ |
| 99 | + |
| 100 | +FAILURE_PDH_COUNTER_INITIALIZATION: |
| 101 | + hQuery = NULL; |
| 102 | + |
| 103 | + FreeLibrary(hmodPDH); |
| 104 | + hmodPDH = NULL; |
| 105 | + |
| 106 | + return; /* FAILURE */ |
13 | 107 | }
|
14 | 108 |
|
15 | 109 | int CpuMoni_get(void)
|
16 | 110 | {
|
17 |
| - return -1; |
| 111 | + if ( hQuery == NULL ) |
| 112 | + { |
| 113 | + return 0; |
| 114 | + } |
| 115 | + |
| 116 | + PDH_STATUS status; |
| 117 | + PDH_FMT_COUNTERVALUE FmtValue; |
| 118 | + |
| 119 | + // get current data |
| 120 | + status = pPdhCollectQueryData(hQuery); |
| 121 | + if ( status != ERROR_SUCCESS ) |
| 122 | + { |
| 123 | + return 0; |
| 124 | + } |
| 125 | + |
| 126 | + // get cpu counter |
| 127 | + for ( int i = 0; i < MAX_PROCESSOR; ++i ) |
| 128 | + { |
| 129 | + status = pPdhGetFormattedCounterValue(hCPUCounter[i], PDH_FMT_DOUBLE, NULL, &FmtValue); |
| 130 | + if ( status != ERROR_SUCCESS ) |
| 131 | + { |
| 132 | + CPUUsage[i] = 0; |
| 133 | + } |
| 134 | + else |
| 135 | + { |
| 136 | + CPUUsage[i] = (int)(FmtValue.doubleValue + 0.5); |
| 137 | + } |
| 138 | + } |
| 139 | + |
| 140 | + // get total cpu usage |
| 141 | + status = pPdhGetFormattedCounterValue(hTotalCPUCounter, PDH_FMT_DOUBLE, NULL, &FmtValue); |
| 142 | + if ( status != ERROR_SUCCESS ) |
| 143 | + { |
| 144 | + return 0; |
| 145 | + } |
| 146 | + |
| 147 | + return (int)(FmtValue.doubleValue + 0.5); |
18 | 148 | }
|
19 | 149 |
|
20 | 150 | void CpuMoni_end(void)
|
21 | 151 | {
|
| 152 | + // finalize |
| 153 | + if ( pPdhCloseQuery ) |
| 154 | + { |
| 155 | + pPdhCloseQuery(hQuery); |
| 156 | + FreeLibrary(hmodPDH); |
| 157 | + } |
| 158 | + |
| 159 | + hQuery = NULL; |
| 160 | + hmodPDH = NULL; |
22 | 161 | }
|
23 | 162 |
|
24 | 163 | #endif /* TC_ENABLE_CPU */
|
0 commit comments