From da9a2b1d3d86eeeeaea6380620c7ab315e8c142d Mon Sep 17 00:00:00 2001 From: Oleg Efimov Date: Tue, 18 Feb 2014 12:35:19 +0400 Subject: [PATCH] unix, windows: add uv_getrusage() function --- include/uv.h | 30 ++++++++++++++++++++++++++++++ src/unix/core.c | 32 ++++++++++++++++++++++++++++++++ src/win/util.c | 37 +++++++++++++++++++++++++++++++++++++ test/test-platform-output.c | 15 +++++++++++++++ 4 files changed, 114 insertions(+) diff --git a/include/uv.h b/include/uv.h index 21a33780..c1b60730 100644 --- a/include/uv.h +++ b/include/uv.h @@ -1669,6 +1669,36 @@ UV_EXTERN int uv_set_process_title(const char* title); UV_EXTERN int uv_resident_set_memory(size_t* rss); UV_EXTERN int uv_uptime(double* uptime); +typedef struct { + long tv_sec; + long tv_usec; +} uv_timeval_t; + +typedef struct { + uv_timeval_t ru_utime; /* user CPU time used */ + uv_timeval_t ru_stime; /* system CPU time used */ + uint64_t ru_maxrss; /* maximum resident set size */ + uint64_t ru_ixrss; /* integral shared memory size */ + uint64_t ru_idrss; /* integral unshared data size */ + uint64_t ru_isrss; /* integral unshared stack size */ + uint64_t ru_minflt; /* page reclaims (soft page faults) */ + uint64_t ru_majflt; /* page faults (hard page faults) */ + uint64_t ru_nswap; /* swaps */ + uint64_t ru_inblock; /* block input operations */ + uint64_t ru_oublock; /* block output operations */ + uint64_t ru_msgsnd; /* IPC messages sent */ + uint64_t ru_msgrcv; /* IPC messages received */ + uint64_t ru_nsignals; /* signals received */ + uint64_t ru_nvcsw; /* voluntary context switches */ + uint64_t ru_nivcsw; /* involuntary context switches */ +} uv_rusage_t; + +/* + * Get information about OS resource utilization for the current process. + * Please note that not all uv_rusage_t struct fields will be filled on Windows. + */ +UV_EXTERN int uv_getrusage(uv_rusage_t* rusage); + /* * This allocates cpu_infos array, and sets count. The array * is freed using uv_free_cpu_info(). diff --git a/src/unix/core.c b/src/unix/core.c index df2a5f80..a8430449 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -37,6 +37,7 @@ #include #include /* INT_MAX, PATH_MAX */ #include /* writev */ +#include /* getrusage */ #ifdef __linux__ # include @@ -785,3 +786,34 @@ int uv__io_active(const uv__io_t* w, unsigned int events) { assert(0 != events); return 0 != (w->pevents & events); } + + +int uv_getrusage(uv_rusage_t* rusage) { + struct rusage usage; + + if (getrusage(RUSAGE_SELF, &usage)) + return -errno; + + rusage->ru_utime.tv_sec = usage.ru_utime.tv_sec; + rusage->ru_utime.tv_usec = usage.ru_utime.tv_usec; + + rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec; + rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec; + + rusage->ru_maxrss = usage.ru_maxrss; + rusage->ru_ixrss = usage.ru_ixrss; + rusage->ru_idrss = usage.ru_idrss; + rusage->ru_isrss = usage.ru_isrss; + rusage->ru_minflt = usage.ru_minflt; + rusage->ru_majflt = usage.ru_majflt; + rusage->ru_nswap = usage.ru_nswap; + rusage->ru_inblock = usage.ru_inblock; + rusage->ru_oublock = usage.ru_oublock; + rusage->ru_msgsnd = usage.ru_msgsnd; + rusage->ru_msgrcv = usage.ru_msgrcv; + rusage->ru_nsignals = usage.ru_nsignals; + rusage->ru_nvcsw = usage.ru_nvcsw; + rusage->ru_nivcsw = usage.ru_nivcsw; + + return 0; +} diff --git a/src/win/util.c b/src/win/util.c index 266b8816..c9ca773d 100644 --- a/src/win/util.c +++ b/src/win/util.c @@ -36,6 +36,7 @@ #include #include #include +#include /* @@ -988,3 +989,39 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { free(addresses); } + + +int uv_getrusage(uv_rusage_t *uv_rusage) { + FILETIME createTime, exitTime, kernelTime, userTime; + SYSTEMTIME kernelSystemTime, userSystemTime; + int ret; + + ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime); + if (ret == 0) { + return uv_translate_sys_error(GetLastError()); + } + + ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime); + if (ret == 0) { + return uv_translate_sys_error(GetLastError()); + } + + ret = FileTimeToSystemTime(&userTime, &userSystemTime); + if (ret == 0) { + return uv_translate_sys_error(GetLastError()); + } + + memset(uv_rusage, 0, sizeof(*uv_rusage)); + + uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 + + userSystemTime.wMinute * 60 + + userSystemTime.wSecond; + uv_rusage->ru_utime.tv_usec = userSystemTime.wMilliseconds * 1000; + + uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 + + kernelSystemTime.wMinute * 60 + + kernelSystemTime.wSecond; + uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000; + + return 0; +} diff --git a/test/test-platform-output.c b/test/test-platform-output.c index d2104f40..93131198 100644 --- a/test/test-platform-output.c +++ b/test/test-platform-output.c @@ -28,6 +28,7 @@ TEST_IMPL(platform_output) { char buffer[512]; size_t rss; double uptime; + uv_rusage_t rusage; uv_cpu_info_t* cpus; uv_interface_address_t* interfaces; int count; @@ -47,6 +48,20 @@ TEST_IMPL(platform_output) { ASSERT(uptime > 0); printf("uv_uptime: %f\n", uptime); + err = uv_getrusage(&rusage); + ASSERT(err == 0); + ASSERT(rusage.ru_utime.tv_sec >= 0); + ASSERT(rusage.ru_utime.tv_usec >= 0); + ASSERT(rusage.ru_stime.tv_sec >= 0); + ASSERT(rusage.ru_stime.tv_usec >= 0); + printf("uv_getrusage:\n"); + printf(" user: %llu sec %llu microsec\n", + (unsigned long long) rusage.ru_utime.tv_sec, + (unsigned long long) rusage.ru_utime.tv_usec); + printf(" system: %llu sec %llu microsec\n", + (unsigned long long) rusage.ru_stime.tv_sec, + (unsigned long long) rusage.ru_stime.tv_usec); + err = uv_cpu_info(&cpus, &count); ASSERT(err == 0);