fix cpu idle metric for windows NT and 2000
This commit is contained in:
parent
9347442bad
commit
b1acfcf5e9
|
@ -84,6 +84,19 @@ typedef DWORD (CALLBACK *LPGETUDPTABLE)(PMIB_UDPTABLE, PDWORD, BOOL);
|
|||
typedef DWORD (CALLBACK *LPGETTCPEXTABLE)(PMIB_TCPEXTABLE *, BOOL, HANDLE,
|
||||
DWORD, DWORD);
|
||||
|
||||
typedef DWORD (CALLBACK *LPSYSINFO)(DWORD, PVOID, ULONG, PULONG);
|
||||
|
||||
/* no longer in the standard header files */
|
||||
typedef struct {
|
||||
LARGE_INTEGER IdleTime;
|
||||
LARGE_INTEGER KernelTime;
|
||||
LARGE_INTEGER UserTime;
|
||||
LARGE_INTEGER Reserved1[2];
|
||||
ULONG Reserved2;
|
||||
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
|
||||
|
||||
#define SystemProcessorPerformanceInformation 8
|
||||
|
||||
typedef struct {
|
||||
sigar_pid_t pid;
|
||||
int ppid;
|
||||
|
@ -105,11 +118,13 @@ struct sigar_t {
|
|||
char *perfbuf;
|
||||
DWORD perfbuf_size;
|
||||
HINSTANCE ip_handle;
|
||||
HINSTANCE nt_handle;
|
||||
LPGETIFTABLE get_if_table;
|
||||
LPGETIPFORWARDTABLE get_ipforward_table;
|
||||
LPGETTCPTABLE get_tcp_table;
|
||||
LPGETTCPEXTABLE get_tcpx_table;
|
||||
LPGETUDPTABLE get_udp_table;
|
||||
LPSYSINFO get_ntsys_info;
|
||||
sigar_win32_pinfo_t pinfo;
|
||||
WORD ws_version;
|
||||
int ws_error;
|
||||
|
|
|
@ -179,13 +179,24 @@ int sigar_os_open(sigar_t **sigar)
|
|||
"TcpExTableFromStack");
|
||||
(*sigar)->get_udp_table =
|
||||
(LPGETUDPTABLE)GetProcAddress(h, "GetUdpTable");
|
||||
(*sigar)->ip_handle = h;
|
||||
}
|
||||
else {
|
||||
(*sigar)->get_if_table = NULL;
|
||||
(*sigar)->get_ipforward_table = NULL;
|
||||
(*sigar)->ip_handle = NULL;
|
||||
}
|
||||
|
||||
if ((h = LoadLibrary("Ntdll.dll"))) {
|
||||
(*sigar)->get_ntsys_info =
|
||||
(LPSYSINFO)GetProcAddress(h, "NtQuerySystemInformation");
|
||||
(*sigar)->nt_handle = h;
|
||||
}
|
||||
else {
|
||||
(*sigar)->get_ntsys_info = NULL;
|
||||
(*sigar)->nt_handle = NULL;
|
||||
}
|
||||
|
||||
(*sigar)->ip_handle = h;
|
||||
(*sigar)->pinfo.pid = -1;
|
||||
(*sigar)->ws_version = 0;
|
||||
(*sigar)->ncpu = 0;
|
||||
|
@ -208,6 +219,10 @@ int sigar_os_close(sigar_t *sigar)
|
|||
FreeLibrary(sigar->ip_handle);
|
||||
}
|
||||
|
||||
if (sigar->nt_handle) {
|
||||
FreeLibrary(sigar->nt_handle);
|
||||
}
|
||||
|
||||
if (sigar->ws_version != 0) {
|
||||
WSACleanup();
|
||||
}
|
||||
|
@ -329,6 +344,53 @@ static PERF_INSTANCE_DEFINITION *get_cpu_instance(sigar_t *sigar,
|
|||
return PdhFirstInstance(object);
|
||||
}
|
||||
|
||||
static int get_idle_cpu(sigar_t *sigar, sigar_cpu_t *cpu,
|
||||
DWORD idx,
|
||||
PERF_COUNTER_BLOCK *counter_block,
|
||||
DWORD *perf_offsets)
|
||||
{
|
||||
cpu->idle = 0;
|
||||
|
||||
if (perf_offsets[PERF_IX_CPU_IDLE]) {
|
||||
cpu->idle = PERF_VAL(PERF_IX_CPU_IDLE);
|
||||
}
|
||||
else {
|
||||
/* windows NT and 2000 do not have an Idle counter */
|
||||
sigar_cpu_count(sigar);
|
||||
if (sigar->get_ntsys_info) {
|
||||
DWORD retval, num;
|
||||
/* XXX unhardcode 16 */
|
||||
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION info[16];
|
||||
|
||||
sigar->get_ntsys_info(SystemProcessorPerformanceInformation,
|
||||
&info, sizeof(info), &retval);
|
||||
|
||||
if (!retval) {
|
||||
return GetLastError();
|
||||
}
|
||||
num = retval/sizeof(info[0]);
|
||||
|
||||
if (idx == -1) {
|
||||
int i;
|
||||
for (i=0; i<num; i++) {
|
||||
cpu->idle += info[i].IdleTime.QuadPart;
|
||||
}
|
||||
}
|
||||
else if (idx < num) {
|
||||
cpu->idle = info[idx].IdleTime.QuadPart;
|
||||
}
|
||||
else {
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
}
|
||||
|
||||
return SIGAR_OK;
|
||||
}
|
||||
|
||||
SIGAR_DECLARE(int) sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu)
|
||||
{
|
||||
PERF_INSTANCE_DEFINITION *inst;
|
||||
|
@ -349,7 +411,7 @@ SIGAR_DECLARE(int) sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu)
|
|||
|
||||
cpu->sys = PERF_VAL(PERF_IX_CPU_SYS);
|
||||
cpu->user = PERF_VAL(PERF_IX_CPU_USER);
|
||||
cpu->idle = PERF_VAL(PERF_IX_CPU_IDLE);
|
||||
get_idle_cpu(sigar, cpu, -1, counter_block, perf_offsets);
|
||||
cpu->nice = 0; /* no nice here */
|
||||
|
||||
cpu->total = cpu->sys + cpu->user + cpu->idle;
|
||||
|
@ -408,7 +470,7 @@ SIGAR_DECLARE(int) sigar_cpu_list_get(sigar_t *sigar, sigar_cpu_list_t *cpulist)
|
|||
|
||||
cpu->sys += PERF_VAL(PERF_IX_CPU_SYS);
|
||||
cpu->user += PERF_VAL(PERF_IX_CPU_USER);
|
||||
cpu->idle += PERF_VAL(PERF_IX_CPU_IDLE);
|
||||
get_idle_cpu(sigar, cpu, i, counter_block, perf_offsets);
|
||||
cpu->nice = 0; /* no nice here */
|
||||
|
||||
cpu->total += cpu->sys + cpu->user + cpu->idle;
|
||||
|
|
Loading…
Reference in New Issue