win: use GetTickCount64 for uptime again (#3470)
Reverts 442aa1f469, since this is an
improved API in Windows Vista that is now usable as a replacement. It
simplifies the code substantially, while returning nearly the same
result (on my system, the performance counters were 6 seconds behind).
The old code also did not work on Wine-5.0 (where I observed that
`data_size == data_block->HeaderLength`, and so no data was present).
This commit is contained in:
parent
939a05633f
commit
d0e500c876
@ -531,103 +531,8 @@ int uv_resident_set_memory(size_t* rss) {
|
||||
|
||||
|
||||
int uv_uptime(double* uptime) {
|
||||
BYTE stack_buffer[4096];
|
||||
BYTE* malloced_buffer = NULL;
|
||||
BYTE* buffer = (BYTE*) stack_buffer;
|
||||
size_t buffer_size = sizeof(stack_buffer);
|
||||
DWORD data_size;
|
||||
|
||||
PERF_DATA_BLOCK* data_block;
|
||||
PERF_OBJECT_TYPE* object_type;
|
||||
PERF_COUNTER_DEFINITION* counter_definition;
|
||||
|
||||
DWORD i;
|
||||
|
||||
for (;;) {
|
||||
LONG result;
|
||||
|
||||
data_size = (DWORD) buffer_size;
|
||||
result = RegQueryValueExW(HKEY_PERFORMANCE_DATA,
|
||||
L"2",
|
||||
NULL,
|
||||
NULL,
|
||||
buffer,
|
||||
&data_size);
|
||||
if (result == ERROR_SUCCESS) {
|
||||
break;
|
||||
} else if (result != ERROR_MORE_DATA) {
|
||||
*uptime = 0;
|
||||
return uv_translate_sys_error(result);
|
||||
}
|
||||
|
||||
buffer_size *= 2;
|
||||
/* Don't let the buffer grow infinitely. */
|
||||
if (buffer_size > 1 << 20) {
|
||||
goto internalError;
|
||||
}
|
||||
|
||||
uv__free(malloced_buffer);
|
||||
|
||||
buffer = malloced_buffer = (BYTE*) uv__malloc(buffer_size);
|
||||
if (malloced_buffer == NULL) {
|
||||
*uptime = 0;
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (data_size < sizeof(*data_block))
|
||||
goto internalError;
|
||||
|
||||
data_block = (PERF_DATA_BLOCK*) buffer;
|
||||
|
||||
if (wmemcmp(data_block->Signature, L"PERF", 4) != 0)
|
||||
goto internalError;
|
||||
|
||||
if (data_size < data_block->HeaderLength + sizeof(*object_type))
|
||||
goto internalError;
|
||||
|
||||
object_type = (PERF_OBJECT_TYPE*) (buffer + data_block->HeaderLength);
|
||||
|
||||
if (object_type->NumInstances != PERF_NO_INSTANCES)
|
||||
goto internalError;
|
||||
|
||||
counter_definition = (PERF_COUNTER_DEFINITION*) (buffer +
|
||||
data_block->HeaderLength + object_type->HeaderLength);
|
||||
for (i = 0; i < object_type->NumCounters; i++) {
|
||||
if ((BYTE*) counter_definition + sizeof(*counter_definition) >
|
||||
buffer + data_size) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (counter_definition->CounterNameTitleIndex == 674 &&
|
||||
counter_definition->CounterSize == sizeof(uint64_t)) {
|
||||
if (counter_definition->CounterOffset + sizeof(uint64_t) > data_size ||
|
||||
!(counter_definition->CounterType & PERF_OBJECT_TIMER)) {
|
||||
goto internalError;
|
||||
} else {
|
||||
BYTE* address = (BYTE*) object_type + object_type->DefinitionLength +
|
||||
counter_definition->CounterOffset;
|
||||
uint64_t value = *((uint64_t*) address);
|
||||
*uptime = (double) (object_type->PerfTime.QuadPart - value) /
|
||||
(double) object_type->PerfFreq.QuadPart;
|
||||
uv__free(malloced_buffer);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
counter_definition = (PERF_COUNTER_DEFINITION*)
|
||||
((BYTE*) counter_definition + counter_definition->ByteLength);
|
||||
}
|
||||
|
||||
/* If we get here, the uptime value was not found. */
|
||||
uv__free(malloced_buffer);
|
||||
*uptime = 0;
|
||||
return UV_ENOSYS;
|
||||
|
||||
internalError:
|
||||
uv__free(malloced_buffer);
|
||||
*uptime = 0;
|
||||
return UV_EIO;
|
||||
*uptime = GetTickCount64() / 1000.0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user