*/
function wfProfileIn( $functionname ) {
global $wgProfiler;
- if ( isset( $wgProfiler['class'] ) ) {
+ if ( $wgProfiler instanceof Profiler || isset( $wgProfiler['class'] ) ) {
Profiler::instance()->profileIn( $functionname );
}
}
*/
function wfProfileOut( $functionname = 'missing' ) {
global $wgProfiler;
- if ( isset( $wgProfiler['class'] ) ) {
+ if ( $wgProfiler instanceof Profiler || isset( $wgProfiler['class'] ) ) {
Profiler::instance()->profileOut( $functionname );
}
}
private static $__instance = null;
function __construct( $params ) {
- // Push an entry for the pre-profile setup time onto the stack
- global $wgRequestTime;
- if ( !empty( $wgRequestTime ) ) {
- $this->mWorkStack[] = array( '-total', 0, $wgRequestTime, 0 );
- $this->mStack[] = array( '-setup', 1, $wgRequestTime, 0, microtime(true), 0 );
- } else {
- $this->profileIn( '-total' );
- }
if ( isset( $params['timeMetric'] ) ) {
$this->mTimeMetric = $params['timeMetric'];
}
if ( isset( $params['profileID'] ) ) {
$this->mProfileID = $params['profileID'];
}
+
+ $this->addInitialStack();
}
/**
if( is_array( $wgProfiler ) ) {
if( !isset( $wgProfiler['class'] ) ) {
wfDebug( __METHOD__ . " called without \$wgProfiler['class']"
- . " set, falling back to ProfilerStub for safety" );
+ . " set, falling back to ProfilerStub for safety\n" );
$class = 'ProfilerStub';
} else {
$class = $wgProfiler['class'];
}
}
+ /**
+ * Add the inital item in the stack.
+ */
+ protected function addInitialStack() {
+ // Push an entry for the pre-profile setup time onto the stack
+ $initial = $this->getInitialTime();
+ if ( $initial !== null ) {
+ $this->mWorkStack[] = array( '-total', 0, $initial, 0 );
+ $this->mStack[] = array( '-setup', 1, $initial, 0, $this->getTime(), 0 );
+ } else {
+ $this->profileIn( '-total' );
+ }
+ }
+
/**
* Called by wfProfieIn()
*
if( $functionname == 'close' ){
$message = "Profile section ended by close(): {$bit[0]}";
$this->debug( "$message\n" );
- $this->mStack[] = array( $message, 0, '0 0', 0, '0 0', 0 );
+ $this->mStack[] = array( $message, 0, 0.0, 0, 0.0, 0 );
}
elseif( $bit[0] != $functionname ){
$message = "Profiling error: in({$bit[0]}), out($functionname)";
$this->debug( "$message\n" );
- $this->mStack[] = array( $message, 0, '0 0', 0, '0 0', 0 );
+ $this->mStack[] = array( $message, 0, 0.0, 0, 0.0, 0 );
}
//}
$bit[] = $time;
/**
* Returns a tree of function call instead of a list of functions
+ * @return string
*/
function getCallTree() {
return implode( '', array_map( array( &$this, 'getCallTreeLine' ), $this->remapCallTree( $this->mStack ) ) );
/**
* Recursive function the format the current profiling array into a tree
*
- * @param $stack profiling array
+ * @param $stack array profiling array
+ * @return array
*/
function remapCallTree( $stack ) {
if( count( $stack ) < 2 ){
/**
* Callback to get a formatted line for the call tree
+ * @return string
*/
function getCallTreeLine( $entry ) {
list( $fname, $level, $start, /* $x */, $end) = $entry;
if ( $this->mTimeMetric === 'user' ) {
return $this->getUserTime();
} else {
- return microtime(true);
+ return microtime( true );
}
}
function getUserTime() {
$ru = getrusage();
- return $ru['ru_utime.tv_sec'].' '.$ru['ru_utime.tv_usec'] / 1e6;
+ return $ru['ru_utime.tv_sec'] + $ru['ru_utime.tv_usec'] / 1e6;
+ }
+
+ private function getInitialTime() {
+ global $wgRequestTime, $wgRUstart;
+
+ if ( $this->mTimeMetric === 'user' ) {
+ if ( count( $wgRUstart ) ) {
+ return $wgRUstart['ru_utime.tv_sec'] + $wgRUstart['ru_utime.tv_usec'] / 1e6;
+ } else {
+ return null;
+ }
+ } else {
+ if ( empty( $wgRequestTime ) ) {
+ return null;
+ } else {
+ return $wgRequestTime;
+ }
+ }
}
protected function collateData() {
/**
* Returns a list of profiled functions.
- * Also log it into the database if $wgProfileToDatabase is set to true.
+ *
+ * @return string
*/
function getFunctionReport() {
$this->collateData();
/**
* Get the function name of the current profiling section
+ * @return
*/
function getCurrentSection() {
$elt = end( $this->mWorkStack );