aboutsummaryrefslogtreecommitdiff
path: root/deps/uv/src/win/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'deps/uv/src/win/util.c')
-rw-r--r--deps/uv/src/win/util.c110
1 files changed, 103 insertions, 7 deletions
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 9f731ecfad..f4d5fdbea9 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
+#include <wchar.h>
#include "uv.h"
#include "internal.h"
@@ -359,9 +360,9 @@ uv_err_t uv_get_process_title(char* buffer, size_t size) {
if (!process_title && uv__get_process_title() == -1) {
return uv__new_sys_error(GetLastError());
}
-
+
assert(process_title);
- strncpy(buffer, process_title, size);
+ strncpy(buffer, process_title, size);
LeaveCriticalSection(&process_title_lock);
return uv_ok_;
@@ -385,8 +386,103 @@ uv_err_t uv_resident_set_memory(size_t* rss) {
uv_err_t uv_uptime(double* uptime) {
- *uptime = (double)GetTickCount()/1000.0;
- return uv_ok_;
+ 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__new_sys_error(result);
+ }
+
+ free(malloced_buffer);
+
+ buffer_size *= 2;
+ /* Don't let the buffer grow infinitely. */
+ if (buffer_size > 1 << 20) {
+ goto internalError;
+ }
+
+ buffer = malloced_buffer = (BYTE*) malloc(buffer_size);
+ if (malloced_buffer == NULL) {
+ *uptime = 0;
+ return uv__new_artificial_error(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;
+ free(malloced_buffer);
+ return uv_ok_;
+ }
+ }
+
+ counter_definition = (PERF_COUNTER_DEFINITION*)
+ ((BYTE*) counter_definition + counter_definition->ByteLength);
+ }
+
+ /* If we get here, the uptime value was not found. */
+ free(malloced_buffer);
+ *uptime = 0;
+ return uv__new_artificial_error(UV_ENOSYS);
+
+ internalError:
+ free(malloced_buffer);
+ *uptime = 0;
+ return uv__new_artificial_error(UV_EIO);
}
@@ -412,7 +508,7 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
*count = 0;
- for (i = 0; i < system_info.dwNumberOfProcessors; i++) {
+ for (i = 0; i < system_info.dwNumberOfProcessors; i++) {
_snprintf(key, sizeof(key), "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", i);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, key, 0, KEY_QUERY_VALUE,
@@ -441,7 +537,7 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
RegCloseKey(processor_key);
processor_key = NULL;
-
+
cpu_info = &(*cpu_infos)[i];
/* $TODO: find times on windows */
@@ -569,7 +665,7 @@ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
}
}
}
-
+
assert(name);
address->name = name;