From 22fc3baa7a63c19e44d99deb7dc7a044f6646f98 Mon Sep 17 00:00:00 2001 From: Kalle Sommer Nielsen Date: Wed, 20 May 2015 15:45:37 +0200 Subject: [PATCH] Windows support for getrusage() * See getrusage.c/h for implementation details and limitations * Tests passes and have had their SKIPIF updated * psapi.lib is now linked to by default --- NEWS | 3 +- ext/standard/microtime.c | 9 +- .../general_functions/getrusage_basic.phpt | 5 +- .../general_functions/getrusage_error.phpt | 5 +- .../getrusage_variation1.phpt | 3 +- win32/build/config.w32 | 2 +- win32/build/config.w32.h.in | 2 + win32/build/confutils.js | 2 +- win32/getrusage.c | 75 ++++++++++++ win32/getrusage.h | 114 ++++++++++++++++++ 10 files changed, 206 insertions(+), 14 deletions(-) create mode 100644 win32/getrusage.c create mode 100644 win32/getrusage.h diff --git a/NEWS b/NEWS index 7ca0e33748..0018b8e5af 100644 --- a/NEWS +++ b/NEWS @@ -119,7 +119,7 @@ . Implement request #67106 (Split main fpm config). (Elan Ruusamäe, Remi) - FTP: - . Fixed bug #69082 FTPS support on Windows + . Fixed bug #69082 (FTPS support on Windows). (Anatol) - Intl: . Removed deprecated aliases datefmt_set_timezone_id() and @@ -223,6 +223,7 @@ (Daniel Lowrey) . Added preg_replace_callback_array function. (Wei Dai) . Deprecated salt option to password_hash. (Anthony) + . Added Windows support for getrusage(). (Kalle) - Streams: . Fixed bug #68532 (convert.base64-encode omits padding bytes). diff --git a/ext/standard/microtime.c b/ext/standard/microtime.c index 6d5b8cc695..4b391bbb7d 100644 --- a/ext/standard/microtime.c +++ b/ext/standard/microtime.c @@ -25,6 +25,7 @@ #endif #ifdef PHP_WIN32 #include "win32/time.h" +#include "win32/getrusage.h" #elif defined(NETWARE) #include #include @@ -129,9 +130,14 @@ PHP_FUNCTION(getrusage) } array_init(return_value); + #define PHP_RUSAGE_PARA(a) \ add_assoc_long(return_value, #a, usg.a) -#if !defined( _OSD_POSIX) && !defined(__BEOS__) /* BS2000 has only a few fields in the rusage struct */ + +#ifdef PHP_WIN32 /* Windows only implements a limited amount of fields from the rusage struct */ + PHP_RUSAGE_PARA(ru_majflt); + PHP_RUSAGE_PARA(ru_maxrss); +#elif !defined( _OSD_POSIX) && !defined(__BEOS__) /* BS2000 has only a few fields in the rusage struct*/ PHP_RUSAGE_PARA(ru_oublock); PHP_RUSAGE_PARA(ru_inblock); PHP_RUSAGE_PARA(ru_msgsnd); @@ -150,6 +156,7 @@ PHP_FUNCTION(getrusage) PHP_RUSAGE_PARA(ru_utime.tv_sec); PHP_RUSAGE_PARA(ru_stime.tv_usec); PHP_RUSAGE_PARA(ru_stime.tv_sec); + #undef PHP_RUSAGE_PARA } #endif /* HAVE_GETRUSAGE */ diff --git a/ext/standard/tests/general_functions/getrusage_basic.phpt b/ext/standard/tests/general_functions/getrusage_basic.phpt index 0e5b42c420..b2379a7663 100644 --- a/ext/standard/tests/general_functions/getrusage_basic.phpt +++ b/ext/standard/tests/general_functions/getrusage_basic.phpt @@ -1,10 +1,7 @@ --TEST-- Test getrusage() function: basic test --SKIPIF-- - + --FILE-- + --FILE-- --FILE-- | + +----------------------------------------------------------------------+ + */ + +#include +#include +#include "getrusage.h" + +/* + * Parts of this file is based on code from the OpenVSwitch project, that + * is released under the Apache 2.0 license and is copyright 2014 Nicira, Inc. + * and have been modified to work with PHP. + */ + +static void usage_to_timeval(FILETIME *ft, struct timeval *tv) +{ + ULARGE_INTEGER time; + + time.LowPart = ft->dwLowDateTime; + time.HighPart = ft->dwHighDateTime; + + tv->tv_sec = (zend_long) (time.QuadPart / 10000000); + tv->tv_usec = (zend_long) ((time.QuadPart % 10000000) / 10); +} + +PHPAPI int getrusage(int who, struct rusage *usage) +{ + FILETIME ctime, etime, stime, utime; + + memset(usage, 0, sizeof(struct rusage)); + + if (who == RUSAGE_SELF) { + PROCESS_MEMORY_COUNTERS pmc; + HANDLE proc = GetCurrentProcess(); + + if (!GetProcessTimes(proc, &ctime, &etime, &stime, &utime)) { + return -1; + } else if(!GetProcessMemoryInfo(proc, &pmc, sizeof(pmc))) { + return -1; + } + + usage_to_timeval(&stime, &usage->ru_stime); + usage_to_timeval(&utime, &usage->ru_utime); + + usage->ru_majflt = pmc.PageFaultCount; + usage->ru_maxrss = pmc.PeakWorkingSetSize / 1024; + + return 0; + } else if (who == RUSAGE_THREAD) { + if (!GetThreadTimes(GetCurrentThread(), &ctime, &etime, &stime, &utime)) { + return -1; + } + + usage_to_timeval(&stime, &usage->ru_stime); + usage_to_timeval(&utime, &usage->ru_utime); + + return 0; + } else { + return -1; + } +} \ No newline at end of file diff --git a/win32/getrusage.h b/win32/getrusage.h new file mode 100644 index 0000000000..dd58d6e8db --- /dev/null +++ b/win32/getrusage.h @@ -0,0 +1,114 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 7 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2015 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Kalle Sommer Nielsen | + +----------------------------------------------------------------------+ + */ + +#ifndef HAVE_GETRUSAGE_H +# define HAVE_GETRUSAGE_H + +/* Note, + * + * RUSAGE_CHILDREN is not implemented, and the RUSAGE_THREAD will + * instead be used instead. + */ + +# define RUSAGE_SELF 0 +# define RUSAGE_CHILDREN 1 + +# define RUSAGE_THREAD RUSAGE_CHILDREN + +/* + * Implementation support + * + * RUSAGE_SELF + * ru_utime + * ru_stime + * ru_majflt + * ru_maxrss + * + * RUSAGE_THREAD + * ru_utime + * ru_stime + * + * Not implemented: + * ru_ixrss (unused) + * ru_idrss (unused) + * ru_isrss (unused) + * ru_minflt + * ru_nswap (unused) + * ru_inblock + * ru_oublock + * ru_msgsnd (unused) + * ru_msgrcv (unused) + * ru_nsignals (unused) + * ru_nvcsw + * ru_nivcsw + */ + +struct rusage +{ + /* User time used */ + struct timeval ru_utime; + + /* System time used */ + struct timeval ru_stime; + + /* Integral max resident set size */ + long ru_maxrss; + + /* Integral shared text memory size */ + long ru_ixrss; + + /* Integral unshared data size */ + long ru_idrss; + + /* Integral unshared stack size */ + long ru_isrss; + + /* Page reclaims */ + long ru_minflt; + + /* Page faults */ + long ru_majflt; + + /* Swaps */ + long ru_nswap; + + /* Block input operations */ + long ru_inblock; + + /* Block output operations */ + long ru_oublock; + + /* Messages sent */ + long ru_msgsnd; + + /* Messages received */ + long ru_msgrcv; + + /* Signals received */ + long ru_nsignals; + + /* Voluntary context switches */ + long ru_nvcsw; + + /* Involuntary context switches */ + long ru_nivcsw; +}; + +PHPAPI int getrusage(int who, struct rusage *usage); + +#endif \ No newline at end of file -- 2.40.0