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,
|
typedef DWORD (CALLBACK *LPGETTCPEXTABLE)(PMIB_TCPEXTABLE *, BOOL, HANDLE,
|
||||||
DWORD, DWORD);
|
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 {
|
typedef struct {
|
||||||
sigar_pid_t pid;
|
sigar_pid_t pid;
|
||||||
int ppid;
|
int ppid;
|
||||||
|
@ -105,11 +118,13 @@ struct sigar_t {
|
||||||
char *perfbuf;
|
char *perfbuf;
|
||||||
DWORD perfbuf_size;
|
DWORD perfbuf_size;
|
||||||
HINSTANCE ip_handle;
|
HINSTANCE ip_handle;
|
||||||
|
HINSTANCE nt_handle;
|
||||||
LPGETIFTABLE get_if_table;
|
LPGETIFTABLE get_if_table;
|
||||||
LPGETIPFORWARDTABLE get_ipforward_table;
|
LPGETIPFORWARDTABLE get_ipforward_table;
|
||||||
LPGETTCPTABLE get_tcp_table;
|
LPGETTCPTABLE get_tcp_table;
|
||||||
LPGETTCPEXTABLE get_tcpx_table;
|
LPGETTCPEXTABLE get_tcpx_table;
|
||||||
LPGETUDPTABLE get_udp_table;
|
LPGETUDPTABLE get_udp_table;
|
||||||
|
LPSYSINFO get_ntsys_info;
|
||||||
sigar_win32_pinfo_t pinfo;
|
sigar_win32_pinfo_t pinfo;
|
||||||
WORD ws_version;
|
WORD ws_version;
|
||||||
int ws_error;
|
int ws_error;
|
||||||
|
|
|
@ -179,13 +179,24 @@ int sigar_os_open(sigar_t **sigar)
|
||||||
"TcpExTableFromStack");
|
"TcpExTableFromStack");
|
||||||
(*sigar)->get_udp_table =
|
(*sigar)->get_udp_table =
|
||||||
(LPGETUDPTABLE)GetProcAddress(h, "GetUdpTable");
|
(LPGETUDPTABLE)GetProcAddress(h, "GetUdpTable");
|
||||||
|
(*sigar)->ip_handle = h;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(*sigar)->get_if_table = NULL;
|
(*sigar)->get_if_table = NULL;
|
||||||
(*sigar)->get_ipforward_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)->pinfo.pid = -1;
|
||||||
(*sigar)->ws_version = 0;
|
(*sigar)->ws_version = 0;
|
||||||
(*sigar)->ncpu = 0;
|
(*sigar)->ncpu = 0;
|
||||||
|
@ -208,6 +219,10 @@ int sigar_os_close(sigar_t *sigar)
|
||||||
FreeLibrary(sigar->ip_handle);
|
FreeLibrary(sigar->ip_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sigar->nt_handle) {
|
||||||
|
FreeLibrary(sigar->nt_handle);
|
||||||
|
}
|
||||||
|
|
||||||
if (sigar->ws_version != 0) {
|
if (sigar->ws_version != 0) {
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
}
|
}
|
||||||
|
@ -329,6 +344,53 @@ static PERF_INSTANCE_DEFINITION *get_cpu_instance(sigar_t *sigar,
|
||||||
return PdhFirstInstance(object);
|
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)
|
SIGAR_DECLARE(int) sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu)
|
||||||
{
|
{
|
||||||
PERF_INSTANCE_DEFINITION *inst;
|
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->sys = PERF_VAL(PERF_IX_CPU_SYS);
|
||||||
cpu->user = PERF_VAL(PERF_IX_CPU_USER);
|
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->nice = 0; /* no nice here */
|
||||||
|
|
||||||
cpu->total = cpu->sys + cpu->user + cpu->idle;
|
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->sys += PERF_VAL(PERF_IX_CPU_SYS);
|
||||||
cpu->user += PERF_VAL(PERF_IX_CPU_USER);
|
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->nice = 0; /* no nice here */
|
||||||
|
|
||||||
cpu->total += cpu->sys + cpu->user + cpu->idle;
|
cpu->total += cpu->sys + cpu->user + cpu->idle;
|
||||||
|
|
Loading…
Reference in New Issue