From d0d9d4eee19ba963a2eae250f3ba118e5d74ab49 Mon Sep 17 00:00:00 2001 From: D3Hunter Date: Wed, 24 Jun 2015 15:08:30 +0800 Subject: [PATCH 1/3] fix bug in sigar_disk_usage_get and change counter index --- src/os/win32/win32_sigar.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/os/win32/win32_sigar.c b/src/os/win32/win32_sigar.c index cbe94a4e5..688d193a8 100755 --- a/src/os/win32/win32_sigar.c +++ b/src/os/win32/win32_sigar.c @@ -93,9 +93,9 @@ typedef enum { PERF_IX_DISK_MAX } perf_disk_offsets_t; -#define PERF_TITLE_DISK_TIME 200 /* % Disk Time */ -#define PERF_TITLE_DISK_READ_TIME 202 /* % Disk Read Time */ -#define PERF_TITLE_DISK_WRITE_TIME 204 /* % Disk Write Time */ +#define PERF_TITLE_DISK_TIME 1400 /* % Disk Time */ +#define PERF_TITLE_DISK_READ_TIME 1402 /* % Disk Read Time */ +#define PERF_TITLE_DISK_WRITE_TIME 1404 /* % Disk Write Time */ #define PERF_TITLE_DISK_READ 214 /* Disk Reads/sec */ #define PERF_TITLE_DISK_WRITE 216 /* Disk Writes/sec */ #define PERF_TITLE_DISK_READ_BYTES 220 /* Disk Read Bytes/sec */ @@ -122,6 +122,11 @@ typedef enum { perf_offsets[ix] ? \ *((DWORD *)((BYTE *)counter_block + perf_offsets[ix])) : 0 +#define PERF_VAL_LARGE(ix) \ + perf_offsets[ix] ? \ + *((ULONGLONG *)((BYTE *)counter_block + perf_offsets[ix])) : 0 + + /* 1/100ns units to milliseconds */ #define NS100_2MSEC(t) ((t) / 10000) @@ -2056,13 +2061,13 @@ SIGAR_DECLARE(int) sigar_disk_usage_get(sigar_t *sigar, } if (strnEQ(drive, dirname, 2)) { - disk->time = PERF_VAL(PERF_IX_DISK_TIME); - disk->rtime = PERF_VAL(PERF_IX_DISK_READ_TIME); - disk->wtime = PERF_VAL(PERF_IX_DISK_WRITE_TIME); + disk->time = PERF_VAL_LARGE(PERF_IX_DISK_TIME); + disk->rtime = PERF_VAL_LARGE(PERF_IX_DISK_READ_TIME); + disk->wtime = PERF_VAL_LARGE(PERF_IX_DISK_WRITE_TIME); disk->reads = PERF_VAL(PERF_IX_DISK_READ); disk->writes = PERF_VAL(PERF_IX_DISK_WRITE); - disk->read_bytes = PERF_VAL(PERF_IX_DISK_READ_BYTES); - disk->write_bytes = PERF_VAL(PERF_IX_DISK_WRITE_BYTES); + disk->read_bytes = PERF_VAL_LARGE(PERF_IX_DISK_READ_BYTES); + disk->write_bytes = PERF_VAL_LARGE(PERF_IX_DISK_WRITE_BYTES); disk->queue = PERF_VAL(PERF_IX_DISK_QUEUE); return SIGAR_OK; } From d3a69bfe0d99bb909d704efe355a2403a59491b3 Mon Sep 17 00:00:00 2001 From: D3Hunter Date: Fri, 21 Aug 2015 10:45:56 +0800 Subject: [PATCH 2/3] fix : incorrect swap space --- src/os/win32/win32_sigar.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/os/win32/win32_sigar.c b/src/os/win32/win32_sigar.c index 688d193a8..36513d90d 100755 --- a/src/os/win32/win32_sigar.c +++ b/src/os/win32/win32_sigar.c @@ -718,14 +718,14 @@ SIGAR_DECLARE(int) sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap) return GetLastError(); } - swap->total = memstat.ullTotalPageFile; - swap->free = memstat.ullAvailPageFile; + swap->total = memstat.ullTotalPageFile - memstat.ullTotalPhys; + swap->free = memstat.ullAvailPageFile - memstat.ullAvailPhys; } else { MEMORYSTATUS memstat; GlobalMemoryStatus(&memstat); - swap->total = memstat.dwTotalPageFile; - swap->free = memstat.dwAvailPageFile; + swap->total = memstat.dwTotalPageFile - memstat.dwTotalPhys; + swap->free = memstat.dwAvailPageFile - memstat.dwAvailPhys; } swap->used = swap->total - swap->free; From 278a57923d034a0d000eb22c1703a0f1c99eec19 Mon Sep 17 00:00:00 2001 From: D3Hunter Date: Fri, 21 Aug 2015 17:56:51 +0800 Subject: [PATCH 3/3] GlobalMemoryStatus* API returns inaccurate result, may cause overflow --- src/os/win32/win32_sigar.c | 69 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/src/os/win32/win32_sigar.c b/src/os/win32/win32_sigar.c index 36513d90d..77e0e4e2f 100755 --- a/src/os/win32/win32_sigar.c +++ b/src/os/win32/win32_sigar.c @@ -35,6 +35,7 @@ #define PERF_TITLE_PROC 230 #define PERF_TITLE_SYS_KEY "2" #define PERF_TITLE_MEM_KEY "4" +#define PERF_TITLE_PAGING_FILE_KEY "700" #define PERF_TITLE_PROC_KEY "230" #define PERF_TITLE_CPU_KEY "238" #define PERF_TITLE_DISK_KEY "236" @@ -294,6 +295,67 @@ static int get_mem_counters(sigar_t *sigar, sigar_swap_t *swap, sigar_mem_t *mem return SIGAR_OK; } +static int get_swap_usage(sigar_t *sigar, sigar_swap_t *swap) +{ + int status; + PERF_OBJECT_TYPE *object = + get_perf_object_inst(sigar, PERF_TITLE_PAGING_FILE_KEY, 0, &status); + PERF_INSTANCE_DEFINITION *inst; + PERF_COUNTER_DEFINITION *counter; + PERF_COUNTER_BLOCK *block; + char name[MAX_PATH]; + char *p; + BYTE *data; + DWORD i; + + if (!object) { + return status; + } + + inst = (PERF_INSTANCE_DEFINITION *)((BYTE *)object + object->DefinitionLength); + + for (i = 0; i < object->NumInstances; i++) { + p = (char *)(((char *)inst) + inst->NameOffset); + + SIGAR_W2A(p, name, sizeof(name)); + + if (stricmp(name, "_Total") == 0) { + break; + } + + block = (PERF_COUNTER_BLOCK*)((LPBYTE)inst + inst->ByteLength); + inst = (PERF_INSTANCE_DEFINITION*)((LPBYTE)block + block->ByteLength); + } + + block = (PERF_COUNTER_BLOCK*)((LPBYTE)inst + inst->ByteLength); + + + for (i=0, counter = PdhFirstCounter(object); + iNumCounters; + i++, counter = PdhNextCounter(counter)) + { + DWORD offset = counter->CounterOffset; + + switch (counter->CounterNameTitleIndex) { + case 702: + data = (LPBYTE)block; + + swap->used = (sigar_uint64_t)(swap->total * ( + (*(DWORD *)(data + offset)) / + (float)(*(DWORD *)(data + (counter+1)->CounterOffset)))); + swap->free = swap->total - swap->used; + + return SIGAR_OK; + default: + continue; + } + } + + /* unreachable */ + + return SIGAR_OK; +} + static void get_sysinfo(sigar_t *sigar) { SYSTEM_INFO sysinfo; @@ -719,16 +781,17 @@ SIGAR_DECLARE(int) sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap) } swap->total = memstat.ullTotalPageFile - memstat.ullTotalPhys; - swap->free = memstat.ullAvailPageFile - memstat.ullAvailPhys; } else { MEMORYSTATUS memstat; GlobalMemoryStatus(&memstat); swap->total = memstat.dwTotalPageFile - memstat.dwTotalPhys; - swap->free = memstat.dwAvailPageFile - memstat.dwAvailPhys; } - swap->used = swap->total - swap->free; + status = get_swap_usage(sigar, swap); + if (status != SIGAR_OK) { + return status; + } if (get_mem_counters(sigar, swap, NULL) != SIGAR_OK) { swap->page_in = SIGAR_FIELD_NOTIMPL;