Merge "Put the sha1 tag in <revision> and not wrongly in <page>"
[lhc/web/wiklou.git] / includes / profiler / Profiler.php
index e535689..f6d8b3a 100644 (file)
@@ -13,7 +13,7 @@
  */
 function wfProfileIn( $functionname ) {
        global $wgProfiler;
-       if ( isset( $wgProfiler['class'] ) ) {
+       if ( $wgProfiler instanceof Profiler || isset( $wgProfiler['class'] ) ) {
                Profiler::instance()->profileIn( $functionname );
        }
 }
@@ -24,7 +24,7 @@ function wfProfileIn( $functionname ) {
  */
 function wfProfileOut( $functionname = 'missing' ) {
        global $wgProfiler;
-       if ( isset( $wgProfiler['class'] ) ) {
+       if ( $wgProfiler instanceof Profiler || isset( $wgProfiler['class'] ) ) {
                Profiler::instance()->profileOut( $functionname );
        }
 }
@@ -41,20 +41,14 @@ class Profiler {
        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();
        }
 
        /**
@@ -67,7 +61,7 @@ class Profiler {
                        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'];
@@ -113,6 +107,20 @@ class Profiler {
                }
        }
 
+       /**
+        * 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()
         *
@@ -150,12 +158,12 @@ class Profiler {
                                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;
@@ -204,6 +212,7 @@ class Profiler {
 
        /**
         * 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 ) ) );
@@ -212,7 +221,8 @@ class Profiler {
        /**
         * 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 ){
@@ -251,6 +261,7 @@ class Profiler {
 
        /**
         * Callback to get a formatted line for the call tree
+        * @return string
         */
        function getCallTreeLine( $entry ) {
                list( $fname, $level, $start, /* $x */, $end)  = $entry;
@@ -265,13 +276,31 @@ class Profiler {
                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() {
@@ -353,7 +382,8 @@ class Profiler {
 
        /**
         * Returns a list of profiled functions.
-        * Also log it into the database if $wgProfileToDatabase is set to true.
+        *
+        * @return string
         */
        function getFunctionReport() {
                $this->collateData();
@@ -474,6 +504,7 @@ class Profiler {
 
        /**
         * Get the function name of the current profiling section
+        * @return
         */
        function getCurrentSection() {
                $elt = end( $this->mWorkStack );