From 4ee9063956ba1a3e7fcc1195b5034f128267ab35 Mon Sep 17 00:00:00 2001 From: Ori Livneh Date: Thu, 4 Sep 2014 16:56:20 -0700 Subject: [PATCH] Under HHVM, measure resources for the thread, not calling process As of , it is possible to call getrusage( [ int $who = 0 ] ) with $who = 2 to request resource usage info for the current thread (RUSAGE_THERAD), rather than the calling process (RUSAGE_SELF). (Earlier versions of HHVM return RUSAGE_SELF data unless $who is 1.) PHP5 code can assume that each request is handled in a dedicated subprocess, but the same is not true of HHVM, which is multi-threaded. Therefore, to get resource usage data for the current request context, it is necessary to ask for RUSAGE_THREAD rather than RUSAGE_SELF. To do this, introduce a new global function in Profiler.php: wfGetRusage(). It is defined there and not in GlobalFunctions.php so that it can be used early in WebStart.php. Bug: 70227 Change-Id: Ibe9598ecdfc0f6c434f8b3c7a94f06a7b2fcca23 --- includes/WebStart.php | 9 ++++----- includes/parser/ParserOutput.php | 10 ++++++---- includes/profiler/Profiler.php | 23 ++++++++++++++++++++--- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/includes/WebStart.php b/includes/WebStart.php index e137628c5e..2ae72dcc00 100644 --- a/includes/WebStart.php +++ b/includes/WebStart.php @@ -40,8 +40,6 @@ if ( ini_get( 'register_globals' ) ) { header( 'X-Content-Type-Options: nosniff' ); $wgRequestTime = microtime( true ); -# getrusage() does not exist on the Microsoft Windows platforms, catching this -$wgRUstart = function_exists( 'getrusage' ) ? getrusage() : array(); unset( $IP ); # Valid web server entry point, enable includes. @@ -60,11 +58,12 @@ if ( $IP === false ) { $IP = realpath( '.' ) ?: dirname( __DIR__ ); } -# Start the autoloader, so that extensions can derive classes from core files -require_once "$IP/includes/AutoLoader.php"; - # Load the profiler require_once "$IP/includes/profiler/Profiler.php"; +$wgRUstart = wfGetRusage() ?: array(); + +# Start the autoloader, so that extensions can derive classes from core files +require_once "$IP/includes/AutoLoader.php"; # Load up some global defines. require_once "$IP/includes/Defines.php"; diff --git a/includes/parser/ParserOutput.php b/includes/parser/ParserOutput.php index f939de35bb..cca6048a0f 100644 --- a/includes/parser/ParserOutput.php +++ b/includes/parser/ParserOutput.php @@ -733,10 +733,12 @@ class ParserOutput extends CacheTime { if ( !$clock || $clock === 'wall' ) { $ret['wall'] = microtime( true ); } - if ( ( !$clock || $clock === 'cpu' ) && function_exists( 'getrusage' ) ) { - $ru = getrusage(); - $ret['cpu'] = $ru['ru_utime.tv_sec'] + $ru['ru_utime.tv_usec'] / 1e6; - $ret['cpu'] += $ru['ru_stime.tv_sec'] + $ru['ru_stime.tv_usec'] / 1e6; + if ( !$clock || $clock === 'cpu' ) { + $ru = wfGetRusage(); + if ( $ru ) { + $ret['cpu'] = $ru['ru_utime.tv_sec'] + $ru['ru_utime.tv_usec'] / 1e6; + $ret['cpu'] += $ru['ru_stime.tv_sec'] + $ru['ru_stime.tv_usec'] / 1e6; + } } return $ret; } diff --git a/includes/profiler/Profiler.php b/includes/profiler/Profiler.php index 7b8f340bab..418b5d48b6 100644 --- a/includes/profiler/Profiler.php +++ b/includes/profiler/Profiler.php @@ -20,9 +20,26 @@ * @file * @ingroup Profiler * @defgroup Profiler Profiler - * This file is only included if profiling is enabled */ +/** + * Get system resource usage of current request context. + * Invokes the getrusage(2) system call, requesting RUSAGE_SELF if on PHP5 + * or RUSAGE_THREAD if on HHVM. Returns false if getrusage is not available. + * + * @since 1.24 + * @return array|bool Resource usage data or false if no data available. + */ +function wfGetRusage() { + if ( !function_exists( 'getrusage' ) ) { + return false; + } elseif ( defined ( 'HHVM_VERSION' ) ) { + return getrusage( 2 /* RUSAGE_THREAD */ ); + } else { + return getrusage( 0 /* RUSAGE_SELF */ ); + } +} + /** * Begin profiling of a function * @param string $functionname Name of the function we will profile @@ -272,10 +289,10 @@ abstract class Profiler { */ protected function getTime( $metric = 'wall' ) { if ( $metric === 'cpu' || $metric === 'user' ) { - if ( !function_exists( 'getrusage' ) ) { + $ru = wfGetRusage(); + if ( !$ru ) { return 0; } - $ru = getrusage(); $time = $ru['ru_utime.tv_sec'] + $ru['ru_utime.tv_usec'] / 1e6; if ( $metric === 'cpu' ) { # This is the time of system calls, added to the user time -- 2.20.1