Index: trunk/phase3/maintenance/doMaintenance.php |
— | — | @@ -74,7 +74,7 @@ |
75 | 75 | if ( !defined( 'MW_COMPILED' ) && file_exists( "$IP/StartProfiler.php" ) ) { |
76 | 76 | require_once( "$IP/StartProfiler.php" ); |
77 | 77 | } else { |
78 | | - require_once( MWInit::compiledPath( 'includes/ProfilerStub.php' ) ); |
| 78 | + require_once( MWInit::compiledPath( 'includes/profiler/ProfilerStub.php' ) ); |
79 | 79 | } |
80 | 80 | |
81 | 81 | // Some other requires |
Index: trunk/phase3/includes/ProfilerSimpleText.php |
— | — | @@ -1,39 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * @file |
5 | | - * @ingroup Profiler |
6 | | - */ |
7 | | - |
8 | | -require_once( dirname( __FILE__ ) . '/ProfilerSimple.php' ); |
9 | | - |
10 | | -/** |
11 | | - * The least sophisticated profiler output class possible, view your source! :) |
12 | | - * |
13 | | - * Put the following 3 lines in StartProfiler.php: |
14 | | - * |
15 | | - * require_once( dirname( __FILE__ ) . '/includes/ProfilerSimpleText.php' ); |
16 | | - * $wgProfiler = new ProfilerSimpleText; |
17 | | - * $wgProfiler->visible=true; |
18 | | - * |
19 | | - * @ingroup Profiler |
20 | | - */ |
21 | | -class ProfilerSimpleText extends ProfilerSimple { |
22 | | - public $visible=false; /* Show as <PRE> or <!-- ? */ |
23 | | - static private $out; |
24 | | - |
25 | | - function getFunctionReport() { |
26 | | - if($this->mTemplated) { |
27 | | - uasort($this->mCollated,array('self','sort')); |
28 | | - array_walk($this->mCollated,array('self','format')); |
29 | | - if ($this->visible) { |
30 | | - print '<pre>'.self::$out.'</pre>'; |
31 | | - } else { |
32 | | - print "<!--\n".self::$out."\n-->\n"; |
33 | | - } |
34 | | - } |
35 | | - } |
36 | | - |
37 | | - /* dense is good */ |
38 | | - static function sort($a,$b) { return $a['real']<$b['real']; /* sort descending by time elapsed */ } |
39 | | - static function format($item,$key) { self::$out .= sprintf("%3.6f %6d - %s\n",$item['real'],$item['count'], $key); } |
40 | | -} |
Index: trunk/phase3/includes/ProfilerStub.php |
— | — | @@ -1,52 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * Stub profiling functions |
5 | | - * @file |
6 | | - * @ingroup Profiler |
7 | | - */ |
8 | | - |
9 | | -/** backward compatibility */ |
10 | | -$wgProfiling = false; |
11 | | -$wgProfiler = null; |
12 | | - |
13 | | -/** is setproctitle function available ? */ |
14 | | -$haveProctitle = function_exists( 'setproctitle' ); |
15 | | - |
16 | | -/** |
17 | | - * Begin profiling of a function |
18 | | - * @param $fn string |
19 | | - */ |
20 | | -function wfProfileIn( $fn = '' ) { |
21 | | - global $hackwhere, $wgDBname, $haveProctitle; |
22 | | - if( $haveProctitle ){ |
23 | | - $hackwhere[] = $fn; |
24 | | - setproctitle( $fn . " [$wgDBname]" ); |
25 | | - } |
26 | | -} |
27 | | - |
28 | | -/** |
29 | | - * Stop profiling of a function |
30 | | - * @param $fn string |
31 | | - */ |
32 | | -function wfProfileOut( $fn = '' ) { |
33 | | - global $hackwhere, $wgDBname, $haveProctitle; |
34 | | - if( !$haveProctitle ) { |
35 | | - return; |
36 | | - } |
37 | | - if( count( $hackwhere ) ) { |
38 | | - array_pop( $hackwhere ); |
39 | | - } |
40 | | - if( count( $hackwhere ) ) { |
41 | | - setproctitle( $hackwhere[count( $hackwhere )-1] . " [$wgDBname]" ); |
42 | | - } |
43 | | -} |
44 | | - |
45 | | -/** |
46 | | - * Does nothing, just for compatibility |
47 | | - */ |
48 | | -function wfGetProfilingOutput( $s, $e ) {} |
49 | | - |
50 | | -/** |
51 | | - * Does nothing, just for compatibility |
52 | | - */ |
53 | | -function wfProfileClose() {} |
Index: trunk/phase3/includes/Profiler.php |
— | — | @@ -1,470 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * @defgroup Profiler Profiler |
5 | | - * |
6 | | - * @file |
7 | | - * @ingroup Profiler |
8 | | - * This file is only included if profiling is enabled |
9 | | - */ |
10 | | - |
11 | | -/** backward compatibility */ |
12 | | -$wgProfiling = true; |
13 | | - |
14 | | -/** |
15 | | - * Begin profiling of a function |
16 | | - * @param $functionname String: name of the function we will profile |
17 | | - */ |
18 | | -function wfProfileIn( $functionname ) { |
19 | | - global $wgProfiler; |
20 | | - $wgProfiler->profileIn( $functionname ); |
21 | | -} |
22 | | - |
23 | | -/** |
24 | | - * Stop profiling of a function |
25 | | - * @param $functionname String: name of the function we have profiled |
26 | | - */ |
27 | | -function wfProfileOut( $functionname = 'missing' ) { |
28 | | - global $wgProfiler; |
29 | | - $wgProfiler->profileOut( $functionname ); |
30 | | -} |
31 | | - |
32 | | -/** |
33 | | - * Returns a profiling output to be stored in debug file |
34 | | - * |
35 | | - * @param $start Float |
36 | | - * @param $elapsed Float: time elapsed since the beginning of the request |
37 | | - */ |
38 | | -function wfGetProfilingOutput( $start, $elapsed ) { |
39 | | - global $wgProfiler; |
40 | | - return $wgProfiler->getOutput( $start, $elapsed ); |
41 | | -} |
42 | | - |
43 | | -/** |
44 | | - * Close opened profiling sections |
45 | | - */ |
46 | | -function wfProfileClose() { |
47 | | - global $wgProfiler; |
48 | | - $wgProfiler->close(); |
49 | | -} |
50 | | - |
51 | | -if (!function_exists('memory_get_usage')) { |
52 | | - # Old PHP or --enable-memory-limit not compiled in |
53 | | - function memory_get_usage() { |
54 | | - return 0; |
55 | | - } |
56 | | -} |
57 | | - |
58 | | -/** |
59 | | - * @ingroup Profiler |
60 | | - * @todo document |
61 | | - */ |
62 | | -class Profiler { |
63 | | - var $mStack = array (), $mWorkStack = array (), $mCollated = array (); |
64 | | - var $mCalls = array (), $mTotals = array (); |
65 | | - var $mTemplated = false; |
66 | | - |
67 | | - function __construct() { |
68 | | - // Push an entry for the pre-profile setup time onto the stack |
69 | | - global $wgRequestTime; |
70 | | - if ( !empty( $wgRequestTime ) ) { |
71 | | - $this->mWorkStack[] = array( '-total', 0, $wgRequestTime, 0 ); |
72 | | - $this->mStack[] = array( '-setup', 1, $wgRequestTime, 0, microtime(true), 0 ); |
73 | | - } else { |
74 | | - $this->profileIn( '-total' ); |
75 | | - } |
76 | | - } |
77 | | - |
78 | | - /** |
79 | | - * Called by wfProfieIn() |
80 | | - * |
81 | | - * @param $functionname String |
82 | | - */ |
83 | | - function profileIn( $functionname ) { |
84 | | - global $wgDebugFunctionEntry, $wgProfiling; |
85 | | - if( !$wgProfiling ) return; |
86 | | - if( $wgDebugFunctionEntry ){ |
87 | | - $this->debug( str_repeat( ' ', count( $this->mWorkStack ) ) . 'Entering ' . $functionname . "\n" ); |
88 | | - } |
89 | | - |
90 | | - $this->mWorkStack[] = array( $functionname, count( $this->mWorkStack ), $this->getTime(), memory_get_usage() ); |
91 | | - } |
92 | | - |
93 | | - /** |
94 | | - * Called by wfProfieOut() |
95 | | - * |
96 | | - * @param $functionname String |
97 | | - */ |
98 | | - function profileOut($functionname) { |
99 | | - global $wgDebugFunctionEntry, $wgProfiling; |
100 | | - if( !$wgProfiling ) return; |
101 | | - $memory = memory_get_usage(); |
102 | | - $time = $this->getTime(); |
103 | | - |
104 | | - if( $wgDebugFunctionEntry ){ |
105 | | - $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" ); |
106 | | - } |
107 | | - |
108 | | - $bit = array_pop($this->mWorkStack); |
109 | | - |
110 | | - if (!$bit) { |
111 | | - $this->debug("Profiling error, !\$bit: $functionname\n"); |
112 | | - } else { |
113 | | - //if( $wgDebugProfiling ){ |
114 | | - if( $functionname == 'close' ){ |
115 | | - $message = "Profile section ended by close(): {$bit[0]}"; |
116 | | - $this->debug( "$message\n" ); |
117 | | - $this->mStack[] = array( $message, 0, '0 0', 0, '0 0', 0 ); |
118 | | - } |
119 | | - elseif( $bit[0] != $functionname ){ |
120 | | - $message = "Profiling error: in({$bit[0]}), out($functionname)"; |
121 | | - $this->debug( "$message\n" ); |
122 | | - $this->mStack[] = array( $message, 0, '0 0', 0, '0 0', 0 ); |
123 | | - } |
124 | | - //} |
125 | | - $bit[] = $time; |
126 | | - $bit[] = $memory; |
127 | | - $this->mStack[] = $bit; |
128 | | - } |
129 | | - } |
130 | | - |
131 | | - /** |
132 | | - * called by wfProfileClose() |
133 | | - */ |
134 | | - function close() { |
135 | | - global $wgProfiling; |
136 | | - |
137 | | - # Avoid infinite loop |
138 | | - if( !$wgProfiling ) |
139 | | - return; |
140 | | - |
141 | | - while( count( $this->mWorkStack ) ){ |
142 | | - $this->profileOut( 'close' ); |
143 | | - } |
144 | | - } |
145 | | - |
146 | | - /** |
147 | | - * Mark this call as templated or not |
148 | | - * |
149 | | - * @param $t Boolean |
150 | | - */ |
151 | | - function setTemplated( $t ) { |
152 | | - $this->mTemplated = $t; |
153 | | - } |
154 | | - |
155 | | - /** |
156 | | - * Called by wfGetProfilingOutput() |
157 | | - */ |
158 | | - function getOutput() { |
159 | | - global $wgDebugFunctionEntry, $wgProfileCallTree; |
160 | | - $wgDebugFunctionEntry = false; |
161 | | - |
162 | | - if( !count( $this->mStack ) && !count( $this->mCollated ) ){ |
163 | | - return "No profiling output\n"; |
164 | | - } |
165 | | - $this->close(); |
166 | | - |
167 | | - if( $wgProfileCallTree ) { |
168 | | - global $wgProfileToDatabase; |
169 | | - # XXX: We must call $this->getFunctionReport() to log to the DB |
170 | | - if( $wgProfileToDatabase ) { |
171 | | - $this->getFunctionReport(); |
172 | | - } |
173 | | - return $this->getCallTree(); |
174 | | - } else { |
175 | | - return $this->getFunctionReport(); |
176 | | - } |
177 | | - } |
178 | | - |
179 | | - /** |
180 | | - * Returns a tree of function call instead of a list of functions |
181 | | - */ |
182 | | - function getCallTree() { |
183 | | - return implode( '', array_map( array( &$this, 'getCallTreeLine' ), $this->remapCallTree( $this->mStack ) ) ); |
184 | | - } |
185 | | - |
186 | | - /** |
187 | | - * Recursive function the format the current profiling array into a tree |
188 | | - * |
189 | | - * @param $stack profiling array |
190 | | - */ |
191 | | - function remapCallTree( $stack ) { |
192 | | - if( count( $stack ) < 2 ){ |
193 | | - return $stack; |
194 | | - } |
195 | | - $outputs = array (); |
196 | | - for( $max = count( $stack ) - 1; $max > 0; ){ |
197 | | - /* Find all items under this entry */ |
198 | | - $level = $stack[$max][1]; |
199 | | - $working = array (); |
200 | | - for( $i = $max -1; $i >= 0; $i-- ){ |
201 | | - if( $stack[$i][1] > $level ){ |
202 | | - $working[] = $stack[$i]; |
203 | | - } else { |
204 | | - break; |
205 | | - } |
206 | | - } |
207 | | - $working = $this->remapCallTree( array_reverse( $working ) ); |
208 | | - $output = array(); |
209 | | - foreach( $working as $item ){ |
210 | | - array_push( $output, $item ); |
211 | | - } |
212 | | - array_unshift( $output, $stack[$max] ); |
213 | | - $max = $i; |
214 | | - |
215 | | - array_unshift( $outputs, $output ); |
216 | | - } |
217 | | - $final = array(); |
218 | | - foreach( $outputs as $output ){ |
219 | | - foreach( $output as $item ){ |
220 | | - $final[] = $item; |
221 | | - } |
222 | | - } |
223 | | - return $final; |
224 | | - } |
225 | | - |
226 | | - /** |
227 | | - * Callback to get a formatted line for the call tree |
228 | | - */ |
229 | | - function getCallTreeLine( $entry ) { |
230 | | - list( $fname, $level, $start, /* $x */, $end) = $entry; |
231 | | - $delta = $end - $start; |
232 | | - $space = str_repeat(' ', $level); |
233 | | - # The ugly double sprintf is to work around a PHP bug, |
234 | | - # which has been fixed in recent releases. |
235 | | - return sprintf( "%10s %s %s\n", trim( sprintf( "%7.3f", $delta * 1000.0 ) ), $space, $fname ); |
236 | | - } |
237 | | - |
238 | | - function getTime() { |
239 | | - return microtime(true); |
240 | | - #return $this->getUserTime(); |
241 | | - } |
242 | | - |
243 | | - function getUserTime() { |
244 | | - $ru = getrusage(); |
245 | | - return $ru['ru_utime.tv_sec'].' '.$ru['ru_utime.tv_usec'] / 1e6; |
246 | | - } |
247 | | - |
248 | | - /** |
249 | | - * Returns a list of profiled functions. |
250 | | - * Also log it into the database if $wgProfileToDatabase is set to true. |
251 | | - */ |
252 | | - function getFunctionReport() { |
253 | | - global $wgProfileToDatabase; |
254 | | - |
255 | | - $width = 140; |
256 | | - $nameWidth = $width - 65; |
257 | | - $format = "%-{$nameWidth}s %6d %13.3f %13.3f %13.3f%% %9d (%13.3f -%13.3f) [%d]\n"; |
258 | | - $titleFormat = "%-{$nameWidth}s %6s %13s %13s %13s %9s\n"; |
259 | | - $prof = "\nProfiling data\n"; |
260 | | - $prof .= sprintf( $titleFormat, 'Name', 'Calls', 'Total', 'Each', '%', 'Mem' ); |
261 | | - $this->mCollated = array (); |
262 | | - $this->mCalls = array (); |
263 | | - $this->mMemory = array (); |
264 | | - |
265 | | - # Estimate profiling overhead |
266 | | - $profileCount = count($this->mStack); |
267 | | - self::calculateOverhead( $profileCount ); |
268 | | - |
269 | | - # First, subtract the overhead! |
270 | | - $overheadTotal = $overheadMemory = $overheadInternal = array(); |
271 | | - foreach( $this->mStack as $entry ){ |
272 | | - $fname = $entry[0]; |
273 | | - $start = $entry[2]; |
274 | | - $end = $entry[4]; |
275 | | - $elapsed = $end - $start; |
276 | | - $memory = $entry[5] - $entry[3]; |
277 | | - |
278 | | - if( $fname == '-overhead-total' ){ |
279 | | - $overheadTotal[] = $elapsed; |
280 | | - $overheadMemory[] = $memory; |
281 | | - } |
282 | | - elseif( $fname == '-overhead-internal' ){ |
283 | | - $overheadInternal[] = $elapsed; |
284 | | - } |
285 | | - } |
286 | | - $overheadTotal = $overheadTotal ? array_sum( $overheadTotal ) / count( $overheadInternal ) : 0; |
287 | | - $overheadMemory = $overheadMemory ? array_sum( $overheadMemory ) / count( $overheadInternal ) : 0; |
288 | | - $overheadInternal = $overheadInternal ? array_sum( $overheadInternal ) / count( $overheadInternal ) : 0; |
289 | | - |
290 | | - # Collate |
291 | | - foreach( $this->mStack as $index => $entry ){ |
292 | | - $fname = $entry[0]; |
293 | | - $start = $entry[2]; |
294 | | - $end = $entry[4]; |
295 | | - $elapsed = $end - $start; |
296 | | - |
297 | | - $memory = $entry[5] - $entry[3]; |
298 | | - $subcalls = $this->calltreeCount( $this->mStack, $index ); |
299 | | - |
300 | | - if( !preg_match( '/^-overhead/', $fname ) ){ |
301 | | - # Adjust for profiling overhead (except special values with elapsed=0 |
302 | | - if( $elapsed ) { |
303 | | - $elapsed -= $overheadInternal; |
304 | | - $elapsed -= ($subcalls * $overheadTotal); |
305 | | - $memory -= ($subcalls * $overheadMemory); |
306 | | - } |
307 | | - } |
308 | | - |
309 | | - if( !array_key_exists( $fname, $this->mCollated ) ){ |
310 | | - $this->mCollated[$fname] = 0; |
311 | | - $this->mCalls[$fname] = 0; |
312 | | - $this->mMemory[$fname] = 0; |
313 | | - $this->mMin[$fname] = 1 << 24; |
314 | | - $this->mMax[$fname] = 0; |
315 | | - $this->mOverhead[$fname] = 0; |
316 | | - } |
317 | | - |
318 | | - $this->mCollated[$fname] += $elapsed; |
319 | | - $this->mCalls[$fname]++; |
320 | | - $this->mMemory[$fname] += $memory; |
321 | | - $this->mMin[$fname] = min($this->mMin[$fname], $elapsed); |
322 | | - $this->mMax[$fname] = max($this->mMax[$fname], $elapsed); |
323 | | - $this->mOverhead[$fname] += $subcalls; |
324 | | - } |
325 | | - |
326 | | - $total = @$this->mCollated['-total']; |
327 | | - $this->mCalls['-overhead-total'] = $profileCount; |
328 | | - |
329 | | - # Output |
330 | | - arsort( $this->mCollated, SORT_NUMERIC ); |
331 | | - foreach( $this->mCollated as $fname => $elapsed ){ |
332 | | - $calls = $this->mCalls[$fname]; |
333 | | - $percent = $total ? 100. * $elapsed / $total : 0; |
334 | | - $memory = $this->mMemory[$fname]; |
335 | | - $prof .= sprintf($format, substr($fname, 0, $nameWidth), $calls, (float) ($elapsed * 1000), (float) ($elapsed * 1000) / $calls, $percent, $memory, ($this->mMin[$fname] * 1000.0), ($this->mMax[$fname] * 1000.0), $this->mOverhead[$fname]); |
336 | | - # Log to the DB |
337 | | - if( $wgProfileToDatabase ) { |
338 | | - self::logToDB($fname, (float) ($elapsed * 1000), $calls, (float) ($memory) ); |
339 | | - } |
340 | | - } |
341 | | - $prof .= "\nTotal: $total\n\n"; |
342 | | - |
343 | | - return $prof; |
344 | | - } |
345 | | - |
346 | | - /** |
347 | | - * Dummy calls to wfProfileIn/wfProfileOut to calculate its overhead |
348 | | - */ |
349 | | - protected static function calculateOverhead( $profileCount ) { |
350 | | - wfProfileIn( '-overhead-total' ); |
351 | | - for( $i = 0; $i < $profileCount; $i++ ){ |
352 | | - wfProfileIn( '-overhead-internal' ); |
353 | | - wfProfileOut( '-overhead-internal' ); |
354 | | - } |
355 | | - wfProfileOut( '-overhead-total' ); |
356 | | - } |
357 | | - |
358 | | - /** |
359 | | - * Counts the number of profiled function calls sitting under |
360 | | - * the given point in the call graph. Not the most efficient algo. |
361 | | - * |
362 | | - * @param $stack Array: |
363 | | - * @param $start Integer: |
364 | | - * @return Integer |
365 | | - * @private |
366 | | - */ |
367 | | - function calltreeCount($stack, $start) { |
368 | | - $level = $stack[$start][1]; |
369 | | - $count = 0; |
370 | | - for ($i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i --) { |
371 | | - $count ++; |
372 | | - } |
373 | | - return $count; |
374 | | - } |
375 | | - |
376 | | - /** |
377 | | - * Log a function into the database. |
378 | | - * |
379 | | - * @param $name String: function name |
380 | | - * @param $timeSum Float |
381 | | - * @param $eventCount Integer: number of times that function was called |
382 | | - * @param $memorySum Integer: memory used by the function |
383 | | - */ |
384 | | - static function logToDB( $name, $timeSum, $eventCount, $memorySum ){ |
385 | | - # Do not log anything if database is readonly (bug 5375) |
386 | | - if( wfReadOnly() ) { return; } |
387 | | - |
388 | | - global $wgProfilePerHost; |
389 | | - |
390 | | - $dbw = wfGetDB( DB_MASTER ); |
391 | | - if( !is_object( $dbw ) ) |
392 | | - return false; |
393 | | - $errorState = $dbw->ignoreErrors( true ); |
394 | | - |
395 | | - $name = substr($name, 0, 255); |
396 | | - |
397 | | - if( $wgProfilePerHost ){ |
398 | | - $pfhost = wfHostname(); |
399 | | - } else { |
400 | | - $pfhost = ''; |
401 | | - } |
402 | | - |
403 | | - // Kludge |
404 | | - $timeSum = ($timeSum >= 0) ? $timeSum : 0; |
405 | | - $memorySum = ($memorySum >= 0) ? $memorySum : 0; |
406 | | - |
407 | | - $dbw->update( 'profiling', |
408 | | - array( |
409 | | - "pf_count=pf_count+{$eventCount}", |
410 | | - "pf_time=pf_time+{$timeSum}", |
411 | | - "pf_memory=pf_memory+{$memorySum}", |
412 | | - ), |
413 | | - array( |
414 | | - 'pf_name' => $name, |
415 | | - 'pf_server' => $pfhost, |
416 | | - ), |
417 | | - __METHOD__ ); |
418 | | - |
419 | | - |
420 | | - $rc = $dbw->affectedRows(); |
421 | | - if ($rc == 0) { |
422 | | - $dbw->insert('profiling', array ('pf_name' => $name, 'pf_count' => $eventCount, |
423 | | - 'pf_time' => $timeSum, 'pf_memory' => $memorySum, 'pf_server' => $pfhost ), |
424 | | - __METHOD__, array ('IGNORE')); |
425 | | - } |
426 | | - // When we upgrade to mysql 4.1, the insert+update |
427 | | - // can be merged into just a insert with this construct added: |
428 | | - // "ON DUPLICATE KEY UPDATE ". |
429 | | - // "pf_count=pf_count + VALUES(pf_count), ". |
430 | | - // "pf_time=pf_time + VALUES(pf_time)"; |
431 | | - $dbw->ignoreErrors( $errorState ); |
432 | | - } |
433 | | - |
434 | | - /** |
435 | | - * Get the function name of the current profiling section |
436 | | - */ |
437 | | - function getCurrentSection() { |
438 | | - $elt = end( $this->mWorkStack ); |
439 | | - return $elt[0]; |
440 | | - } |
441 | | - |
442 | | - /** |
443 | | - * Get function caller |
444 | | - * |
445 | | - * @param $level Integer |
446 | | - */ |
447 | | - static function getCaller( $level ) { |
448 | | - $backtrace = wfDebugBacktrace(); |
449 | | - if ( isset( $backtrace[$level] ) ) { |
450 | | - if ( isset( $backtrace[$level]['class'] ) ) { |
451 | | - $caller = $backtrace[$level]['class'] . '::' . $backtrace[$level]['function']; |
452 | | - } else { |
453 | | - $caller = $backtrace[$level]['function']; |
454 | | - } |
455 | | - } else { |
456 | | - $caller = 'unknown'; |
457 | | - } |
458 | | - return $caller; |
459 | | - } |
460 | | - |
461 | | - /** |
462 | | - * Add an entry in the debug log file |
463 | | - * |
464 | | - * @param $s String to output |
465 | | - */ |
466 | | - function debug( $s ) { |
467 | | - if( function_exists( 'wfDebug' ) ) { |
468 | | - wfDebug( $s ); |
469 | | - } |
470 | | - } |
471 | | -} |
Index: trunk/phase3/includes/ProfilerSimpleTrace.php |
— | — | @@ -1,71 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * @file |
5 | | - * @ingroup Profiler |
6 | | - */ |
7 | | - |
8 | | -if ( !class_exists( 'ProfilerSimple' ) ) { |
9 | | - require_once(dirname(__FILE__).'/ProfilerSimple.php'); |
10 | | -} |
11 | | - |
12 | | -/** |
13 | | - * Execution trace |
14 | | - * @todo document methods (?) |
15 | | - * @ingroup Profiler |
16 | | - */ |
17 | | -class ProfilerSimpleTrace extends ProfilerSimple { |
18 | | - var $mMinimumTime = 0; |
19 | | - var $mProfileID = false; |
20 | | - var $trace = ""; |
21 | | - var $memory = 0; |
22 | | - |
23 | | - function __construct() { |
24 | | - global $wgRequestTime, $wgRUstart; |
25 | | - if ( !empty( $wgRequestTime ) && !empty( $wgRUstart ) ) { |
26 | | - $this->mWorkStack[] = array( '-total', 0, $wgRequestTime, $this->getCpuTime( $wgRUstart ) ); |
27 | | - } |
28 | | - $this->trace .= "Beginning trace: \n"; |
29 | | - } |
30 | | - |
31 | | - function profileIn($functionname) { |
32 | | - $this->mWorkStack[] = array($functionname, count( $this->mWorkStack ), microtime(true), $this->getCpuTime()); |
33 | | - $this->trace .= " " . sprintf("%6.1f",$this->memoryDiff()) . |
34 | | - str_repeat( " ", count($this->mWorkStack)) . " > " . $functionname . "\n"; |
35 | | - } |
36 | | - |
37 | | - function profileOut($functionname) { |
38 | | - global $wgDebugFunctionEntry; |
39 | | - |
40 | | - if ( $wgDebugFunctionEntry ) { |
41 | | - $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n"); |
42 | | - } |
43 | | - |
44 | | - list( $ofname, /* $ocount */ , $ortime, $octime ) = array_pop( $this->mWorkStack ); |
45 | | - |
46 | | - if ( !$ofname ) { |
47 | | - $this->trace .= "Profiling error: $functionname\n"; |
48 | | - } else { |
49 | | - if ( $functionname == 'close' ) { |
50 | | - $message = "Profile section ended by close(): {$ofname}"; |
51 | | - $functionname = $ofname; |
52 | | - $this->trace .= $message . "\n"; |
53 | | - } |
54 | | - elseif ( $ofname != $functionname ) { |
55 | | - $this->trace .= "Profiling error: in({$ofname}), out($functionname)"; |
56 | | - } |
57 | | - $elapsedreal = microtime( true ) - $ortime; |
58 | | - $this->trace .= sprintf( "%03.6f %6.1f", $elapsedreal, $this->memoryDiff() ) . |
59 | | - str_repeat(" ", count( $this->mWorkStack ) + 1 ) . " < " . $functionname . "\n"; |
60 | | - } |
61 | | - } |
62 | | - |
63 | | - function memoryDiff() { |
64 | | - $diff = memory_get_usage() - $this->memory; |
65 | | - $this->memory = memory_get_usage(); |
66 | | - return $diff / 1024; |
67 | | - } |
68 | | - |
69 | | - function getOutput() { |
70 | | - print "<!-- \n {$this->trace} \n -->"; |
71 | | - } |
72 | | -} |
Index: trunk/phase3/includes/ProfilerSimple.php |
— | — | @@ -1,130 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * @file |
5 | | - * @ingroup Profiler |
6 | | - */ |
7 | | - |
8 | | -if ( !class_exists( 'Profiler' ) ) { |
9 | | - require_once(dirname(__FILE__).'/Profiler.php'); |
10 | | -} |
11 | | - |
12 | | -/** |
13 | | - * Simple profiler base class. |
14 | | - * @todo document methods (?) |
15 | | - * @ingroup Profiler |
16 | | - */ |
17 | | -class ProfilerSimple extends Profiler { |
18 | | - var $mMinimumTime = 0; |
19 | | - var $mProfileID = false; |
20 | | - |
21 | | - function __construct() { |
22 | | - global $wgRequestTime, $wgRUstart; |
23 | | - if (!empty($wgRequestTime) && !empty($wgRUstart)) { |
24 | | - $this->mWorkStack[] = array( '-total', 0, $wgRequestTime,$this->getCpuTime($wgRUstart)); |
25 | | - |
26 | | - $elapsedcpu = $this->getCpuTime() - $this->getCpuTime($wgRUstart); |
27 | | - $elapsedreal = microtime(true) - $wgRequestTime; |
28 | | - |
29 | | - $entry =& $this->mCollated["-setup"]; |
30 | | - if (!is_array($entry)) { |
31 | | - $entry = array('cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0); |
32 | | - $this->mCollated["-setup"] =& $entry; |
33 | | - } |
34 | | - $entry['cpu'] += $elapsedcpu; |
35 | | - $entry['cpu_sq'] += $elapsedcpu*$elapsedcpu; |
36 | | - $entry['real'] += $elapsedreal; |
37 | | - $entry['real_sq'] += $elapsedreal*$elapsedreal; |
38 | | - $entry['count']++; |
39 | | - } |
40 | | - } |
41 | | - |
42 | | - function setMinimum( $min ) { |
43 | | - $this->mMinimumTime = $min; |
44 | | - } |
45 | | - |
46 | | - function setProfileID( $id ) { |
47 | | - $this->mProfileID = $id; |
48 | | - } |
49 | | - |
50 | | - function getProfileID() { |
51 | | - if ( $this->mProfileID === false ) { |
52 | | - return wfWikiID(); |
53 | | - } else { |
54 | | - return $this->mProfileID; |
55 | | - } |
56 | | - } |
57 | | - |
58 | | - function profileIn($functionname) { |
59 | | - global $wgDebugFunctionEntry; |
60 | | - if ($wgDebugFunctionEntry) { |
61 | | - $this->debug(str_repeat(' ', count($this->mWorkStack)).'Entering '.$functionname."\n"); |
62 | | - } |
63 | | - $this->mWorkStack[] = array($functionname, count( $this->mWorkStack ), microtime(true), $this->getCpuTime()); |
64 | | - } |
65 | | - |
66 | | - function profileOut($functionname) { |
67 | | - global $wgDebugFunctionEntry; |
68 | | - |
69 | | - if ($wgDebugFunctionEntry) { |
70 | | - $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n"); |
71 | | - } |
72 | | - |
73 | | - list($ofname, /* $ocount */ ,$ortime,$octime) = array_pop($this->mWorkStack); |
74 | | - |
75 | | - if (!$ofname) { |
76 | | - $this->debug("Profiling error: $functionname\n"); |
77 | | - } else { |
78 | | - if ($functionname == 'close') { |
79 | | - $message = "Profile section ended by close(): {$ofname}"; |
80 | | - $functionname = $ofname; |
81 | | - $this->debug( "$message\n" ); |
82 | | - $this->mCollated[$message] = array( |
83 | | - 'real' => 0.0, 'count' => 1); |
84 | | - } |
85 | | - elseif ($ofname != $functionname) { |
86 | | - $message = "Profiling error: in({$ofname}), out($functionname)"; |
87 | | - $this->debug( "$message\n" ); |
88 | | - $this->mCollated[$message] = array( |
89 | | - 'real' => 0.0, 'count' => 1); |
90 | | - } |
91 | | - $entry =& $this->mCollated[$functionname]; |
92 | | - $elapsedcpu = $this->getCpuTime() - $octime; |
93 | | - $elapsedreal = microtime(true) - $ortime; |
94 | | - if (!is_array($entry)) { |
95 | | - $entry = array('cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0); |
96 | | - $this->mCollated[$functionname] =& $entry; |
97 | | - } |
98 | | - $entry['cpu'] += $elapsedcpu; |
99 | | - $entry['cpu_sq'] += $elapsedcpu*$elapsedcpu; |
100 | | - $entry['real'] += $elapsedreal; |
101 | | - $entry['real_sq'] += $elapsedreal*$elapsedreal; |
102 | | - $entry['count']++; |
103 | | - |
104 | | - } |
105 | | - } |
106 | | - |
107 | | - function getFunctionReport() { |
108 | | - /* Implement in output subclasses */ |
109 | | - } |
110 | | - |
111 | | - function getCpuTime($ru=null) { |
112 | | - if ( function_exists( 'getrusage' ) ) { |
113 | | - if ( $ru == null ) { |
114 | | - $ru = getrusage(); |
115 | | - } |
116 | | - return ($ru['ru_utime.tv_sec'] + $ru['ru_stime.tv_sec'] + ($ru['ru_utime.tv_usec'] + |
117 | | - $ru['ru_stime.tv_usec']) * 1e-6); |
118 | | - } else { |
119 | | - return 0; |
120 | | - } |
121 | | - } |
122 | | - |
123 | | - /* If argument is passed, it assumes that it is dual-format time string, returns proper float time value */ |
124 | | - function getTime($time=null) { |
125 | | - if ($time==null) { |
126 | | - return microtime(true); |
127 | | - } |
128 | | - list($a,$b)=explode(" ",$time); |
129 | | - return (float)($a+$b); |
130 | | - } |
131 | | -} |
Index: trunk/phase3/includes/ProfilerSimpleUDP.php |
— | — | @@ -1,41 +0,0 @@ |
2 | | -<?php |
3 | | -/** |
4 | | - * @file |
5 | | - * @ingroup Profiler |
6 | | - */ |
7 | | - |
8 | | -require_once(dirname(__FILE__).'/ProfilerSimple.php'); |
9 | | - |
10 | | -/** |
11 | | - * ProfilerSimpleUDP class, that sends out messages for 'udpprofile' daemon |
12 | | - * (the one from mediawiki/trunk/udpprofile SVN ) |
13 | | - * @ingroup Profiler |
14 | | - */ |
15 | | -class ProfilerSimpleUDP extends ProfilerSimple { |
16 | | - function getFunctionReport() { |
17 | | - global $wgUDPProfilerHost, $wgUDPProfilerPort; |
18 | | - |
19 | | - if ( $this->mCollated['-total']['real'] < $this->mMinimumTime ) { |
20 | | - # Less than minimum, ignore |
21 | | - return; |
22 | | - } |
23 | | - |
24 | | - $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); |
25 | | - $plength=0; |
26 | | - $packet=""; |
27 | | - foreach ($this->mCollated as $entry=>$pfdata) { |
28 | | - $pfline=sprintf ("%s %s %d %f %f %f %f %s\n", $this->getProfileID(),"-",$pfdata['count'], |
29 | | - $pfdata['cpu'],$pfdata['cpu_sq'],$pfdata['real'],$pfdata['real_sq'],$entry); |
30 | | - $length=strlen($pfline); |
31 | | - /* printf("<!-- $pfline -->"); */ |
32 | | - if ($length+$plength>1400) { |
33 | | - socket_sendto($sock,$packet,$plength,0,$wgUDPProfilerHost,$wgUDPProfilerPort); |
34 | | - $packet=""; |
35 | | - $plength=0; |
36 | | - } |
37 | | - $packet.=$pfline; |
38 | | - $plength+=$length; |
39 | | - } |
40 | | - socket_sendto($sock,$packet,$plength,0x100,$wgUDPProfilerHost,$wgUDPProfilerPort); |
41 | | - } |
42 | | -} |
Index: trunk/phase3/includes/profiler/ProfilerSimpleTrace.php |
— | — | @@ -0,0 +1,71 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * @file |
| 5 | + * @ingroup Profiler |
| 6 | + */ |
| 7 | + |
| 8 | +if ( !class_exists( 'ProfilerSimple' ) ) { |
| 9 | + require_once( dirname( __FILE__ ) . '/ProfilerSimple.php' ); |
| 10 | +} |
| 11 | + |
| 12 | +/** |
| 13 | + * Execution trace |
| 14 | + * @todo document methods (?) |
| 15 | + * @ingroup Profiler |
| 16 | + */ |
| 17 | +class ProfilerSimpleTrace extends ProfilerSimple { |
| 18 | + var $mMinimumTime = 0; |
| 19 | + var $mProfileID = false; |
| 20 | + var $trace = ""; |
| 21 | + var $memory = 0; |
| 22 | + |
| 23 | + function __construct() { |
| 24 | + global $wgRequestTime, $wgRUstart; |
| 25 | + if ( !empty( $wgRequestTime ) && !empty( $wgRUstart ) ) { |
| 26 | + $this->mWorkStack[] = array( '-total', 0, $wgRequestTime, $this->getCpuTime( $wgRUstart ) ); |
| 27 | + } |
| 28 | + $this->trace .= "Beginning trace: \n"; |
| 29 | + } |
| 30 | + |
| 31 | + function profileIn($functionname) { |
| 32 | + $this->mWorkStack[] = array($functionname, count( $this->mWorkStack ), microtime(true), $this->getCpuTime()); |
| 33 | + $this->trace .= " " . sprintf("%6.1f",$this->memoryDiff()) . |
| 34 | + str_repeat( " ", count($this->mWorkStack)) . " > " . $functionname . "\n"; |
| 35 | + } |
| 36 | + |
| 37 | + function profileOut($functionname) { |
| 38 | + global $wgDebugFunctionEntry; |
| 39 | + |
| 40 | + if ( $wgDebugFunctionEntry ) { |
| 41 | + $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n"); |
| 42 | + } |
| 43 | + |
| 44 | + list( $ofname, /* $ocount */ , $ortime, $octime ) = array_pop( $this->mWorkStack ); |
| 45 | + |
| 46 | + if ( !$ofname ) { |
| 47 | + $this->trace .= "Profiling error: $functionname\n"; |
| 48 | + } else { |
| 49 | + if ( $functionname == 'close' ) { |
| 50 | + $message = "Profile section ended by close(): {$ofname}"; |
| 51 | + $functionname = $ofname; |
| 52 | + $this->trace .= $message . "\n"; |
| 53 | + } |
| 54 | + elseif ( $ofname != $functionname ) { |
| 55 | + $this->trace .= "Profiling error: in({$ofname}), out($functionname)"; |
| 56 | + } |
| 57 | + $elapsedreal = microtime( true ) - $ortime; |
| 58 | + $this->trace .= sprintf( "%03.6f %6.1f", $elapsedreal, $this->memoryDiff() ) . |
| 59 | + str_repeat(" ", count( $this->mWorkStack ) + 1 ) . " < " . $functionname . "\n"; |
| 60 | + } |
| 61 | + } |
| 62 | + |
| 63 | + function memoryDiff() { |
| 64 | + $diff = memory_get_usage() - $this->memory; |
| 65 | + $this->memory = memory_get_usage(); |
| 66 | + return $diff / 1024; |
| 67 | + } |
| 68 | + |
| 69 | + function getOutput() { |
| 70 | + print "<!-- \n {$this->trace} \n -->"; |
| 71 | + } |
| 72 | +} |
Property changes on: trunk/phase3/includes/profiler/ProfilerSimpleTrace.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 73 | + native |
Index: trunk/phase3/includes/profiler/ProfilerSimple.php |
— | — | @@ -0,0 +1,130 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * @file |
| 5 | + * @ingroup Profiler |
| 6 | + */ |
| 7 | + |
| 8 | +if ( !class_exists( 'Profiler' ) ) { |
| 9 | + require_once( dirname( __FILE__ ) . '/Profiler.php' ); |
| 10 | +} |
| 11 | + |
| 12 | +/** |
| 13 | + * Simple profiler base class. |
| 14 | + * @todo document methods (?) |
| 15 | + * @ingroup Profiler |
| 16 | + */ |
| 17 | +class ProfilerSimple extends Profiler { |
| 18 | + var $mMinimumTime = 0; |
| 19 | + var $mProfileID = false; |
| 20 | + |
| 21 | + function __construct() { |
| 22 | + global $wgRequestTime, $wgRUstart; |
| 23 | + if (!empty($wgRequestTime) && !empty($wgRUstart)) { |
| 24 | + $this->mWorkStack[] = array( '-total', 0, $wgRequestTime,$this->getCpuTime($wgRUstart)); |
| 25 | + |
| 26 | + $elapsedcpu = $this->getCpuTime() - $this->getCpuTime($wgRUstart); |
| 27 | + $elapsedreal = microtime(true) - $wgRequestTime; |
| 28 | + |
| 29 | + $entry =& $this->mCollated["-setup"]; |
| 30 | + if (!is_array($entry)) { |
| 31 | + $entry = array('cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0); |
| 32 | + $this->mCollated["-setup"] =& $entry; |
| 33 | + } |
| 34 | + $entry['cpu'] += $elapsedcpu; |
| 35 | + $entry['cpu_sq'] += $elapsedcpu*$elapsedcpu; |
| 36 | + $entry['real'] += $elapsedreal; |
| 37 | + $entry['real_sq'] += $elapsedreal*$elapsedreal; |
| 38 | + $entry['count']++; |
| 39 | + } |
| 40 | + } |
| 41 | + |
| 42 | + function setMinimum( $min ) { |
| 43 | + $this->mMinimumTime = $min; |
| 44 | + } |
| 45 | + |
| 46 | + function setProfileID( $id ) { |
| 47 | + $this->mProfileID = $id; |
| 48 | + } |
| 49 | + |
| 50 | + function getProfileID() { |
| 51 | + if ( $this->mProfileID === false ) { |
| 52 | + return wfWikiID(); |
| 53 | + } else { |
| 54 | + return $this->mProfileID; |
| 55 | + } |
| 56 | + } |
| 57 | + |
| 58 | + function profileIn($functionname) { |
| 59 | + global $wgDebugFunctionEntry; |
| 60 | + if ($wgDebugFunctionEntry) { |
| 61 | + $this->debug(str_repeat(' ', count($this->mWorkStack)).'Entering '.$functionname."\n"); |
| 62 | + } |
| 63 | + $this->mWorkStack[] = array($functionname, count( $this->mWorkStack ), microtime(true), $this->getCpuTime()); |
| 64 | + } |
| 65 | + |
| 66 | + function profileOut($functionname) { |
| 67 | + global $wgDebugFunctionEntry; |
| 68 | + |
| 69 | + if ($wgDebugFunctionEntry) { |
| 70 | + $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n"); |
| 71 | + } |
| 72 | + |
| 73 | + list($ofname, /* $ocount */ ,$ortime,$octime) = array_pop($this->mWorkStack); |
| 74 | + |
| 75 | + if (!$ofname) { |
| 76 | + $this->debug("Profiling error: $functionname\n"); |
| 77 | + } else { |
| 78 | + if ($functionname == 'close') { |
| 79 | + $message = "Profile section ended by close(): {$ofname}"; |
| 80 | + $functionname = $ofname; |
| 81 | + $this->debug( "$message\n" ); |
| 82 | + $this->mCollated[$message] = array( |
| 83 | + 'real' => 0.0, 'count' => 1); |
| 84 | + } |
| 85 | + elseif ($ofname != $functionname) { |
| 86 | + $message = "Profiling error: in({$ofname}), out($functionname)"; |
| 87 | + $this->debug( "$message\n" ); |
| 88 | + $this->mCollated[$message] = array( |
| 89 | + 'real' => 0.0, 'count' => 1); |
| 90 | + } |
| 91 | + $entry =& $this->mCollated[$functionname]; |
| 92 | + $elapsedcpu = $this->getCpuTime() - $octime; |
| 93 | + $elapsedreal = microtime(true) - $ortime; |
| 94 | + if (!is_array($entry)) { |
| 95 | + $entry = array('cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0); |
| 96 | + $this->mCollated[$functionname] =& $entry; |
| 97 | + } |
| 98 | + $entry['cpu'] += $elapsedcpu; |
| 99 | + $entry['cpu_sq'] += $elapsedcpu*$elapsedcpu; |
| 100 | + $entry['real'] += $elapsedreal; |
| 101 | + $entry['real_sq'] += $elapsedreal*$elapsedreal; |
| 102 | + $entry['count']++; |
| 103 | + |
| 104 | + } |
| 105 | + } |
| 106 | + |
| 107 | + function getFunctionReport() { |
| 108 | + /* Implement in output subclasses */ |
| 109 | + } |
| 110 | + |
| 111 | + function getCpuTime($ru=null) { |
| 112 | + if ( function_exists( 'getrusage' ) ) { |
| 113 | + if ( $ru == null ) { |
| 114 | + $ru = getrusage(); |
| 115 | + } |
| 116 | + return ($ru['ru_utime.tv_sec'] + $ru['ru_stime.tv_sec'] + ($ru['ru_utime.tv_usec'] + |
| 117 | + $ru['ru_stime.tv_usec']) * 1e-6); |
| 118 | + } else { |
| 119 | + return 0; |
| 120 | + } |
| 121 | + } |
| 122 | + |
| 123 | + /* If argument is passed, it assumes that it is dual-format time string, returns proper float time value */ |
| 124 | + function getTime($time=null) { |
| 125 | + if ($time==null) { |
| 126 | + return microtime(true); |
| 127 | + } |
| 128 | + list($a,$b)=explode(" ",$time); |
| 129 | + return (float)($a+$b); |
| 130 | + } |
| 131 | +} |
Property changes on: trunk/phase3/includes/profiler/ProfilerSimple.php |
___________________________________________________________________ |
Added: svn:keywords |
1 | 132 | + Author Date Id Revision |
Added: svn:eol-style |
2 | 133 | + native |
Index: trunk/phase3/includes/profiler/ProfilerStub.php |
— | — | @@ -0,0 +1,65 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * Stub profiling functions |
| 5 | + * @file |
| 6 | + * @ingroup Profiler |
| 7 | + */ |
| 8 | +if ( !class_exists( 'Profiler' ) ) { |
| 9 | + require_once( dirname( __FILE__ ) . '/Profiler.php' ); |
| 10 | +} |
| 11 | + |
| 12 | +class ProfilerStub extends Profiler { |
| 13 | + |
| 14 | + /** |
| 15 | + * is setproctitle function available? |
| 16 | + * @var bool |
| 17 | + */ |
| 18 | + private $haveProctitle; |
| 19 | + private $hackWhere = array(); |
| 20 | + |
| 21 | + /** |
| 22 | + * Constructor. Check for proctitle. |
| 23 | + */ |
| 24 | + public function __construct() { |
| 25 | + $this->haveProctitle = function_exists( 'setproctitle' ); |
| 26 | + } |
| 27 | + |
| 28 | + /** |
| 29 | + * Begin profiling of a function |
| 30 | + * @param $fn string |
| 31 | + */ |
| 32 | + public function profileIn( $fn = '' ) { |
| 33 | + global $wgDBname; |
| 34 | + if( $this->haveProctitle ){ |
| 35 | + $this->hackWhere[] = $fn; |
| 36 | + setproctitle( $fn . " [$wgDBname]" ); |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + /** |
| 41 | + * Stop profiling of a function |
| 42 | + * @param $fn string |
| 43 | + */ |
| 44 | + public function profileOut( $fn = '' ) { |
| 45 | + global $wgDBname; |
| 46 | + if( !$this->haveProctitle ) { |
| 47 | + return; |
| 48 | + } |
| 49 | + if( count( $this->hackWhere ) ) { |
| 50 | + array_pop( $this->hackWhere ); |
| 51 | + } |
| 52 | + if( count( $this->hackWhere ) ) { |
| 53 | + setproctitle( $this->hackWhere[count( $this->hackWhere )-1] . " [$wgDBname]" ); |
| 54 | + } |
| 55 | + } |
| 56 | + |
| 57 | + /** |
| 58 | + * Does nothing, just for compatibility |
| 59 | + */ |
| 60 | + public function getOutput() {} |
| 61 | + public function close() {} |
| 62 | +} |
| 63 | + |
| 64 | +/** backward compatibility */ |
| 65 | +$wgProfiling = false; |
| 66 | +$wgProfiler = new ProfilerStub(); |
Property changes on: trunk/phase3/includes/profiler/ProfilerStub.php |
___________________________________________________________________ |
Added: svn:keywords |
1 | 67 | + Author Date Id Revision |
Added: svn:eol-style |
2 | 68 | + native |
Index: trunk/phase3/includes/profiler/ProfilerSimpleText.php |
— | — | @@ -0,0 +1,41 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * @file |
| 5 | + * @ingroup Profiler |
| 6 | + */ |
| 7 | + |
| 8 | +if ( !class_exists( 'ProfilerSimple' ) ) { |
| 9 | + require_once( dirname( __FILE__ ) . '/ProfilerSimple.php' ); |
| 10 | +} |
| 11 | + |
| 12 | +/** |
| 13 | + * The least sophisticated profiler output class possible, view your source! :) |
| 14 | + * |
| 15 | + * Put the following 3 lines in StartProfiler.php: |
| 16 | + * |
| 17 | + * require_once( dirname( __FILE__ ) . '/includes/ProfilerSimpleText.php' ); |
| 18 | + * $wgProfiler = new ProfilerSimpleText; |
| 19 | + * $wgProfiler->visible=true; |
| 20 | + * |
| 21 | + * @ingroup Profiler |
| 22 | + */ |
| 23 | +class ProfilerSimpleText extends ProfilerSimple { |
| 24 | + public $visible=false; /* Show as <PRE> or <!-- ? */ |
| 25 | + static private $out; |
| 26 | + |
| 27 | + function getFunctionReport() { |
| 28 | + if($this->mTemplated) { |
| 29 | + uasort($this->mCollated,array('self','sort')); |
| 30 | + array_walk($this->mCollated,array('self','format')); |
| 31 | + if ($this->visible) { |
| 32 | + print '<pre>'.self::$out.'</pre>'; |
| 33 | + } else { |
| 34 | + print "<!--\n".self::$out."\n-->\n"; |
| 35 | + } |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + /* dense is good */ |
| 40 | + static function sort($a,$b) { return $a['real']<$b['real']; /* sort descending by time elapsed */ } |
| 41 | + static function format($item,$key) { self::$out .= sprintf("%3.6f %6d - %s\n",$item['real'],$item['count'], $key); } |
| 42 | +} |
Property changes on: trunk/phase3/includes/profiler/ProfilerSimpleText.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 43 | + native |
Index: trunk/phase3/includes/profiler/Profiler.php |
— | — | @@ -0,0 +1,467 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * @defgroup Profiler Profiler |
| 5 | + * |
| 6 | + * @file |
| 7 | + * @ingroup Profiler |
| 8 | + * This file is only included if profiling is enabled |
| 9 | + */ |
| 10 | + |
| 11 | +/** backward compatibility */ |
| 12 | +$wgProfiling = true; |
| 13 | + |
| 14 | +/** |
| 15 | + * Begin profiling of a function |
| 16 | + * @param $functionname String: name of the function we will profile |
| 17 | + */ |
| 18 | +function wfProfileIn( $functionname ) { |
| 19 | + global $wgProfiler; |
| 20 | + $wgProfiler->profileIn( $functionname ); |
| 21 | +} |
| 22 | + |
| 23 | +/** |
| 24 | + * Stop profiling of a function |
| 25 | + * @param $functionname String: name of the function we have profiled |
| 26 | + */ |
| 27 | +function wfProfileOut( $functionname = 'missing' ) { |
| 28 | + global $wgProfiler; |
| 29 | + $wgProfiler->profileOut( $functionname ); |
| 30 | +} |
| 31 | + |
| 32 | +/** |
| 33 | + * Returns a profiling output to be stored in debug file |
| 34 | + */ |
| 35 | +function wfGetProfilingOutput() { |
| 36 | + global $wgProfiler; |
| 37 | + return $wgProfiler->getOutput(); |
| 38 | +} |
| 39 | + |
| 40 | +/** |
| 41 | + * Close opened profiling sections |
| 42 | + */ |
| 43 | +function wfProfileClose() { |
| 44 | + global $wgProfiler; |
| 45 | + $wgProfiler->close(); |
| 46 | +} |
| 47 | + |
| 48 | +if (!function_exists('memory_get_usage')) { |
| 49 | + # Old PHP or --enable-memory-limit not compiled in |
| 50 | + function memory_get_usage() { |
| 51 | + return 0; |
| 52 | + } |
| 53 | +} |
| 54 | + |
| 55 | +/** |
| 56 | + * @ingroup Profiler |
| 57 | + * @todo document |
| 58 | + */ |
| 59 | +class Profiler { |
| 60 | + var $mStack = array (), $mWorkStack = array (), $mCollated = array (); |
| 61 | + var $mCalls = array (), $mTotals = array (); |
| 62 | + var $mTemplated = false; |
| 63 | + |
| 64 | + function __construct() { |
| 65 | + // Push an entry for the pre-profile setup time onto the stack |
| 66 | + global $wgRequestTime; |
| 67 | + if ( !empty( $wgRequestTime ) ) { |
| 68 | + $this->mWorkStack[] = array( '-total', 0, $wgRequestTime, 0 ); |
| 69 | + $this->mStack[] = array( '-setup', 1, $wgRequestTime, 0, microtime(true), 0 ); |
| 70 | + } else { |
| 71 | + $this->profileIn( '-total' ); |
| 72 | + } |
| 73 | + } |
| 74 | + |
| 75 | + /** |
| 76 | + * Called by wfProfieIn() |
| 77 | + * |
| 78 | + * @param $functionname String |
| 79 | + */ |
| 80 | + public function profileIn( $functionname ) { |
| 81 | + global $wgDebugFunctionEntry, $wgProfiling; |
| 82 | + if( !$wgProfiling ) return; |
| 83 | + if( $wgDebugFunctionEntry ){ |
| 84 | + $this->debug( str_repeat( ' ', count( $this->mWorkStack ) ) . 'Entering ' . $functionname . "\n" ); |
| 85 | + } |
| 86 | + |
| 87 | + $this->mWorkStack[] = array( $functionname, count( $this->mWorkStack ), $this->getTime(), memory_get_usage() ); |
| 88 | + } |
| 89 | + |
| 90 | + /** |
| 91 | + * Called by wfProfieOut() |
| 92 | + * |
| 93 | + * @param $functionname String |
| 94 | + */ |
| 95 | + public function profileOut($functionname) { |
| 96 | + global $wgDebugFunctionEntry, $wgProfiling; |
| 97 | + if( !$wgProfiling ) return; |
| 98 | + $memory = memory_get_usage(); |
| 99 | + $time = $this->getTime(); |
| 100 | + |
| 101 | + if( $wgDebugFunctionEntry ){ |
| 102 | + $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" ); |
| 103 | + } |
| 104 | + |
| 105 | + $bit = array_pop($this->mWorkStack); |
| 106 | + |
| 107 | + if (!$bit) { |
| 108 | + $this->debug("Profiling error, !\$bit: $functionname\n"); |
| 109 | + } else { |
| 110 | + //if( $wgDebugProfiling ){ |
| 111 | + if( $functionname == 'close' ){ |
| 112 | + $message = "Profile section ended by close(): {$bit[0]}"; |
| 113 | + $this->debug( "$message\n" ); |
| 114 | + $this->mStack[] = array( $message, 0, '0 0', 0, '0 0', 0 ); |
| 115 | + } |
| 116 | + elseif( $bit[0] != $functionname ){ |
| 117 | + $message = "Profiling error: in({$bit[0]}), out($functionname)"; |
| 118 | + $this->debug( "$message\n" ); |
| 119 | + $this->mStack[] = array( $message, 0, '0 0', 0, '0 0', 0 ); |
| 120 | + } |
| 121 | + //} |
| 122 | + $bit[] = $time; |
| 123 | + $bit[] = $memory; |
| 124 | + $this->mStack[] = $bit; |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + /** |
| 129 | + * called by wfProfileClose() |
| 130 | + */ |
| 131 | + public function close() { |
| 132 | + global $wgProfiling; |
| 133 | + |
| 134 | + # Avoid infinite loop |
| 135 | + if( !$wgProfiling ) |
| 136 | + return; |
| 137 | + |
| 138 | + while( count( $this->mWorkStack ) ){ |
| 139 | + $this->profileOut( 'close' ); |
| 140 | + } |
| 141 | + } |
| 142 | + |
| 143 | + /** |
| 144 | + * Mark this call as templated or not |
| 145 | + * |
| 146 | + * @param $t Boolean |
| 147 | + */ |
| 148 | + function setTemplated( $t ) { |
| 149 | + $this->mTemplated = $t; |
| 150 | + } |
| 151 | + |
| 152 | + /** |
| 153 | + * Called by wfGetProfilingOutput() |
| 154 | + */ |
| 155 | + public function getOutput() { |
| 156 | + global $wgDebugFunctionEntry, $wgProfileCallTree; |
| 157 | + $wgDebugFunctionEntry = false; |
| 158 | + |
| 159 | + if( !count( $this->mStack ) && !count( $this->mCollated ) ){ |
| 160 | + return "No profiling output\n"; |
| 161 | + } |
| 162 | + $this->close(); |
| 163 | + |
| 164 | + if( $wgProfileCallTree ) { |
| 165 | + global $wgProfileToDatabase; |
| 166 | + # XXX: We must call $this->getFunctionReport() to log to the DB |
| 167 | + if( $wgProfileToDatabase ) { |
| 168 | + $this->getFunctionReport(); |
| 169 | + } |
| 170 | + return $this->getCallTree(); |
| 171 | + } else { |
| 172 | + return $this->getFunctionReport(); |
| 173 | + } |
| 174 | + } |
| 175 | + |
| 176 | + /** |
| 177 | + * Returns a tree of function call instead of a list of functions |
| 178 | + */ |
| 179 | + function getCallTree() { |
| 180 | + return implode( '', array_map( array( &$this, 'getCallTreeLine' ), $this->remapCallTree( $this->mStack ) ) ); |
| 181 | + } |
| 182 | + |
| 183 | + /** |
| 184 | + * Recursive function the format the current profiling array into a tree |
| 185 | + * |
| 186 | + * @param $stack profiling array |
| 187 | + */ |
| 188 | + function remapCallTree( $stack ) { |
| 189 | + if( count( $stack ) < 2 ){ |
| 190 | + return $stack; |
| 191 | + } |
| 192 | + $outputs = array (); |
| 193 | + for( $max = count( $stack ) - 1; $max > 0; ){ |
| 194 | + /* Find all items under this entry */ |
| 195 | + $level = $stack[$max][1]; |
| 196 | + $working = array (); |
| 197 | + for( $i = $max -1; $i >= 0; $i-- ){ |
| 198 | + if( $stack[$i][1] > $level ){ |
| 199 | + $working[] = $stack[$i]; |
| 200 | + } else { |
| 201 | + break; |
| 202 | + } |
| 203 | + } |
| 204 | + $working = $this->remapCallTree( array_reverse( $working ) ); |
| 205 | + $output = array(); |
| 206 | + foreach( $working as $item ){ |
| 207 | + array_push( $output, $item ); |
| 208 | + } |
| 209 | + array_unshift( $output, $stack[$max] ); |
| 210 | + $max = $i; |
| 211 | + |
| 212 | + array_unshift( $outputs, $output ); |
| 213 | + } |
| 214 | + $final = array(); |
| 215 | + foreach( $outputs as $output ){ |
| 216 | + foreach( $output as $item ){ |
| 217 | + $final[] = $item; |
| 218 | + } |
| 219 | + } |
| 220 | + return $final; |
| 221 | + } |
| 222 | + |
| 223 | + /** |
| 224 | + * Callback to get a formatted line for the call tree |
| 225 | + */ |
| 226 | + function getCallTreeLine( $entry ) { |
| 227 | + list( $fname, $level, $start, /* $x */, $end) = $entry; |
| 228 | + $delta = $end - $start; |
| 229 | + $space = str_repeat(' ', $level); |
| 230 | + # The ugly double sprintf is to work around a PHP bug, |
| 231 | + # which has been fixed in recent releases. |
| 232 | + return sprintf( "%10s %s %s\n", trim( sprintf( "%7.3f", $delta * 1000.0 ) ), $space, $fname ); |
| 233 | + } |
| 234 | + |
| 235 | + function getTime() { |
| 236 | + return microtime(true); |
| 237 | + #return $this->getUserTime(); |
| 238 | + } |
| 239 | + |
| 240 | + function getUserTime() { |
| 241 | + $ru = getrusage(); |
| 242 | + return $ru['ru_utime.tv_sec'].' '.$ru['ru_utime.tv_usec'] / 1e6; |
| 243 | + } |
| 244 | + |
| 245 | + /** |
| 246 | + * Returns a list of profiled functions. |
| 247 | + * Also log it into the database if $wgProfileToDatabase is set to true. |
| 248 | + */ |
| 249 | + function getFunctionReport() { |
| 250 | + global $wgProfileToDatabase; |
| 251 | + |
| 252 | + $width = 140; |
| 253 | + $nameWidth = $width - 65; |
| 254 | + $format = "%-{$nameWidth}s %6d %13.3f %13.3f %13.3f%% %9d (%13.3f -%13.3f) [%d]\n"; |
| 255 | + $titleFormat = "%-{$nameWidth}s %6s %13s %13s %13s %9s\n"; |
| 256 | + $prof = "\nProfiling data\n"; |
| 257 | + $prof .= sprintf( $titleFormat, 'Name', 'Calls', 'Total', 'Each', '%', 'Mem' ); |
| 258 | + $this->mCollated = array (); |
| 259 | + $this->mCalls = array (); |
| 260 | + $this->mMemory = array (); |
| 261 | + |
| 262 | + # Estimate profiling overhead |
| 263 | + $profileCount = count($this->mStack); |
| 264 | + self::calculateOverhead( $profileCount ); |
| 265 | + |
| 266 | + # First, subtract the overhead! |
| 267 | + $overheadTotal = $overheadMemory = $overheadInternal = array(); |
| 268 | + foreach( $this->mStack as $entry ){ |
| 269 | + $fname = $entry[0]; |
| 270 | + $start = $entry[2]; |
| 271 | + $end = $entry[4]; |
| 272 | + $elapsed = $end - $start; |
| 273 | + $memory = $entry[5] - $entry[3]; |
| 274 | + |
| 275 | + if( $fname == '-overhead-total' ){ |
| 276 | + $overheadTotal[] = $elapsed; |
| 277 | + $overheadMemory[] = $memory; |
| 278 | + } |
| 279 | + elseif( $fname == '-overhead-internal' ){ |
| 280 | + $overheadInternal[] = $elapsed; |
| 281 | + } |
| 282 | + } |
| 283 | + $overheadTotal = $overheadTotal ? array_sum( $overheadTotal ) / count( $overheadInternal ) : 0; |
| 284 | + $overheadMemory = $overheadMemory ? array_sum( $overheadMemory ) / count( $overheadInternal ) : 0; |
| 285 | + $overheadInternal = $overheadInternal ? array_sum( $overheadInternal ) / count( $overheadInternal ) : 0; |
| 286 | + |
| 287 | + # Collate |
| 288 | + foreach( $this->mStack as $index => $entry ){ |
| 289 | + $fname = $entry[0]; |
| 290 | + $start = $entry[2]; |
| 291 | + $end = $entry[4]; |
| 292 | + $elapsed = $end - $start; |
| 293 | + |
| 294 | + $memory = $entry[5] - $entry[3]; |
| 295 | + $subcalls = $this->calltreeCount( $this->mStack, $index ); |
| 296 | + |
| 297 | + if( !preg_match( '/^-overhead/', $fname ) ){ |
| 298 | + # Adjust for profiling overhead (except special values with elapsed=0 |
| 299 | + if( $elapsed ) { |
| 300 | + $elapsed -= $overheadInternal; |
| 301 | + $elapsed -= ($subcalls * $overheadTotal); |
| 302 | + $memory -= ($subcalls * $overheadMemory); |
| 303 | + } |
| 304 | + } |
| 305 | + |
| 306 | + if( !array_key_exists( $fname, $this->mCollated ) ){ |
| 307 | + $this->mCollated[$fname] = 0; |
| 308 | + $this->mCalls[$fname] = 0; |
| 309 | + $this->mMemory[$fname] = 0; |
| 310 | + $this->mMin[$fname] = 1 << 24; |
| 311 | + $this->mMax[$fname] = 0; |
| 312 | + $this->mOverhead[$fname] = 0; |
| 313 | + } |
| 314 | + |
| 315 | + $this->mCollated[$fname] += $elapsed; |
| 316 | + $this->mCalls[$fname]++; |
| 317 | + $this->mMemory[$fname] += $memory; |
| 318 | + $this->mMin[$fname] = min($this->mMin[$fname], $elapsed); |
| 319 | + $this->mMax[$fname] = max($this->mMax[$fname], $elapsed); |
| 320 | + $this->mOverhead[$fname] += $subcalls; |
| 321 | + } |
| 322 | + |
| 323 | + $total = @$this->mCollated['-total']; |
| 324 | + $this->mCalls['-overhead-total'] = $profileCount; |
| 325 | + |
| 326 | + # Output |
| 327 | + arsort( $this->mCollated, SORT_NUMERIC ); |
| 328 | + foreach( $this->mCollated as $fname => $elapsed ){ |
| 329 | + $calls = $this->mCalls[$fname]; |
| 330 | + $percent = $total ? 100. * $elapsed / $total : 0; |
| 331 | + $memory = $this->mMemory[$fname]; |
| 332 | + $prof .= sprintf($format, substr($fname, 0, $nameWidth), $calls, (float) ($elapsed * 1000), (float) ($elapsed * 1000) / $calls, $percent, $memory, ($this->mMin[$fname] * 1000.0), ($this->mMax[$fname] * 1000.0), $this->mOverhead[$fname]); |
| 333 | + # Log to the DB |
| 334 | + if( $wgProfileToDatabase ) { |
| 335 | + self::logToDB($fname, (float) ($elapsed * 1000), $calls, (float) ($memory) ); |
| 336 | + } |
| 337 | + } |
| 338 | + $prof .= "\nTotal: $total\n\n"; |
| 339 | + |
| 340 | + return $prof; |
| 341 | + } |
| 342 | + |
| 343 | + /** |
| 344 | + * Dummy calls to wfProfileIn/wfProfileOut to calculate its overhead |
| 345 | + */ |
| 346 | + protected static function calculateOverhead( $profileCount ) { |
| 347 | + wfProfileIn( '-overhead-total' ); |
| 348 | + for( $i = 0; $i < $profileCount; $i++ ){ |
| 349 | + wfProfileIn( '-overhead-internal' ); |
| 350 | + wfProfileOut( '-overhead-internal' ); |
| 351 | + } |
| 352 | + wfProfileOut( '-overhead-total' ); |
| 353 | + } |
| 354 | + |
| 355 | + /** |
| 356 | + * Counts the number of profiled function calls sitting under |
| 357 | + * the given point in the call graph. Not the most efficient algo. |
| 358 | + * |
| 359 | + * @param $stack Array: |
| 360 | + * @param $start Integer: |
| 361 | + * @return Integer |
| 362 | + * @private |
| 363 | + */ |
| 364 | + function calltreeCount($stack, $start) { |
| 365 | + $level = $stack[$start][1]; |
| 366 | + $count = 0; |
| 367 | + for ($i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i --) { |
| 368 | + $count ++; |
| 369 | + } |
| 370 | + return $count; |
| 371 | + } |
| 372 | + |
| 373 | + /** |
| 374 | + * Log a function into the database. |
| 375 | + * |
| 376 | + * @param $name String: function name |
| 377 | + * @param $timeSum Float |
| 378 | + * @param $eventCount Integer: number of times that function was called |
| 379 | + * @param $memorySum Integer: memory used by the function |
| 380 | + */ |
| 381 | + static function logToDB( $name, $timeSum, $eventCount, $memorySum ){ |
| 382 | + # Do not log anything if database is readonly (bug 5375) |
| 383 | + if( wfReadOnly() ) { return; } |
| 384 | + |
| 385 | + global $wgProfilePerHost; |
| 386 | + |
| 387 | + $dbw = wfGetDB( DB_MASTER ); |
| 388 | + if( !is_object( $dbw ) ) |
| 389 | + return false; |
| 390 | + $errorState = $dbw->ignoreErrors( true ); |
| 391 | + |
| 392 | + $name = substr($name, 0, 255); |
| 393 | + |
| 394 | + if( $wgProfilePerHost ){ |
| 395 | + $pfhost = wfHostname(); |
| 396 | + } else { |
| 397 | + $pfhost = ''; |
| 398 | + } |
| 399 | + |
| 400 | + // Kludge |
| 401 | + $timeSum = ($timeSum >= 0) ? $timeSum : 0; |
| 402 | + $memorySum = ($memorySum >= 0) ? $memorySum : 0; |
| 403 | + |
| 404 | + $dbw->update( 'profiling', |
| 405 | + array( |
| 406 | + "pf_count=pf_count+{$eventCount}", |
| 407 | + "pf_time=pf_time+{$timeSum}", |
| 408 | + "pf_memory=pf_memory+{$memorySum}", |
| 409 | + ), |
| 410 | + array( |
| 411 | + 'pf_name' => $name, |
| 412 | + 'pf_server' => $pfhost, |
| 413 | + ), |
| 414 | + __METHOD__ ); |
| 415 | + |
| 416 | + |
| 417 | + $rc = $dbw->affectedRows(); |
| 418 | + if ($rc == 0) { |
| 419 | + $dbw->insert('profiling', array ('pf_name' => $name, 'pf_count' => $eventCount, |
| 420 | + 'pf_time' => $timeSum, 'pf_memory' => $memorySum, 'pf_server' => $pfhost ), |
| 421 | + __METHOD__, array ('IGNORE')); |
| 422 | + } |
| 423 | + // When we upgrade to mysql 4.1, the insert+update |
| 424 | + // can be merged into just a insert with this construct added: |
| 425 | + // "ON DUPLICATE KEY UPDATE ". |
| 426 | + // "pf_count=pf_count + VALUES(pf_count), ". |
| 427 | + // "pf_time=pf_time + VALUES(pf_time)"; |
| 428 | + $dbw->ignoreErrors( $errorState ); |
| 429 | + } |
| 430 | + |
| 431 | + /** |
| 432 | + * Get the function name of the current profiling section |
| 433 | + */ |
| 434 | + function getCurrentSection() { |
| 435 | + $elt = end( $this->mWorkStack ); |
| 436 | + return $elt[0]; |
| 437 | + } |
| 438 | + |
| 439 | + /** |
| 440 | + * Get function caller |
| 441 | + * |
| 442 | + * @param $level Integer |
| 443 | + */ |
| 444 | + static function getCaller( $level ) { |
| 445 | + $backtrace = wfDebugBacktrace(); |
| 446 | + if ( isset( $backtrace[$level] ) ) { |
| 447 | + if ( isset( $backtrace[$level]['class'] ) ) { |
| 448 | + $caller = $backtrace[$level]['class'] . '::' . $backtrace[$level]['function']; |
| 449 | + } else { |
| 450 | + $caller = $backtrace[$level]['function']; |
| 451 | + } |
| 452 | + } else { |
| 453 | + $caller = 'unknown'; |
| 454 | + } |
| 455 | + return $caller; |
| 456 | + } |
| 457 | + |
| 458 | + /** |
| 459 | + * Add an entry in the debug log file |
| 460 | + * |
| 461 | + * @param $s String to output |
| 462 | + */ |
| 463 | + function debug( $s ) { |
| 464 | + if( function_exists( 'wfDebug' ) ) { |
| 465 | + wfDebug( $s ); |
| 466 | + } |
| 467 | + } |
| 468 | +} |
Property changes on: trunk/phase3/includes/profiler/Profiler.php |
___________________________________________________________________ |
Added: svn:keywords |
1 | 469 | + Author Date Id Revision |
Added: svn:eol-style |
2 | 470 | + native |
Index: trunk/phase3/includes/profiler/ProfilerSimpleUDP.php |
— | — | @@ -0,0 +1,43 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * @file |
| 5 | + * @ingroup Profiler |
| 6 | + */ |
| 7 | + |
| 8 | +if ( !class_exists( 'ProfilerSimple' ) ) { |
| 9 | + require_once( dirname( __FILE__ ) . '/ProfilerSimple.php' ); |
| 10 | +} |
| 11 | + |
| 12 | +/** |
| 13 | + * ProfilerSimpleUDP class, that sends out messages for 'udpprofile' daemon |
| 14 | + * (the one from mediawiki/trunk/udpprofile SVN ) |
| 15 | + * @ingroup Profiler |
| 16 | + */ |
| 17 | +class ProfilerSimpleUDP extends ProfilerSimple { |
| 18 | + function getFunctionReport() { |
| 19 | + global $wgUDPProfilerHost, $wgUDPProfilerPort; |
| 20 | + |
| 21 | + if ( $this->mCollated['-total']['real'] < $this->mMinimumTime ) { |
| 22 | + # Less than minimum, ignore |
| 23 | + return; |
| 24 | + } |
| 25 | + |
| 26 | + $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); |
| 27 | + $plength=0; |
| 28 | + $packet=""; |
| 29 | + foreach ($this->mCollated as $entry=>$pfdata) { |
| 30 | + $pfline=sprintf ("%s %s %d %f %f %f %f %s\n", $this->getProfileID(),"-",$pfdata['count'], |
| 31 | + $pfdata['cpu'],$pfdata['cpu_sq'],$pfdata['real'],$pfdata['real_sq'],$entry); |
| 32 | + $length=strlen($pfline); |
| 33 | + /* printf("<!-- $pfline -->"); */ |
| 34 | + if ($length+$plength>1400) { |
| 35 | + socket_sendto($sock,$packet,$plength,0,$wgUDPProfilerHost,$wgUDPProfilerPort); |
| 36 | + $packet=""; |
| 37 | + $plength=0; |
| 38 | + } |
| 39 | + $packet.=$pfline; |
| 40 | + $plength+=$length; |
| 41 | + } |
| 42 | + socket_sendto($sock,$packet,$plength,0x100,$wgUDPProfilerHost,$wgUDPProfilerPort); |
| 43 | + } |
| 44 | +} |
Property changes on: trunk/phase3/includes/profiler/ProfilerSimpleUDP.php |
___________________________________________________________________ |
Added: svn:keywords |
1 | 45 | + Author Date Id Revision |
Added: svn:eol-style |
2 | 46 | + native |
Index: trunk/phase3/includes/WebStart.php |
— | — | @@ -94,7 +94,7 @@ |
95 | 95 | if ( file_exists( "$IP/StartProfiler.php" ) ) { |
96 | 96 | require_once( "$IP/StartProfiler.php" ); |
97 | 97 | } else { |
98 | | - require_once( "$IP/includes/ProfilerStub.php" ); |
| 98 | + require_once( "$IP/includes/profiler/ProfilerStub.php" ); |
99 | 99 | } |
100 | 100 | |
101 | 101 | # Load up some global defines. |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -185,10 +185,6 @@ |
186 | 186 | 'PoolCounterWork' => 'includes/PoolCounter.php', |
187 | 187 | 'Preferences' => 'includes/Preferences.php', |
188 | 188 | 'PrefixSearch' => 'includes/PrefixSearch.php', |
189 | | - 'Profiler' => 'includes/Profiler.php', |
190 | | - 'ProfilerSimple' => 'includes/ProfilerSimple.php', |
191 | | - 'ProfilerSimpleText' => 'includes/ProfilerSimpleText.php', |
192 | | - 'ProfilerSimpleUDP' => 'includes/ProfilerSimpleUDP.php', |
193 | 189 | 'ProtectionForm' => 'includes/ProtectionForm.php', |
194 | 190 | 'QueryPage' => 'includes/QueryPage.php', |
195 | 191 | 'QuickTemplate' => 'includes/SkinTemplate.php', |
— | — | @@ -599,6 +595,13 @@ |
600 | 596 | 'StripState' => 'includes/parser/StripState.php', |
601 | 597 | 'MWTidy' => 'includes/parser/Tidy.php', |
602 | 598 | |
| 599 | + # includes/profiler |
| 600 | + 'Profiler' => 'includes/Profiler.php', |
| 601 | + 'ProfilerSimple' => 'includes/ProfilerSimple.php', |
| 602 | + 'ProfilerSimpleText' => 'includes/ProfilerSimpleText.php', |
| 603 | + 'ProfilerSimpleUDP' => 'includes/ProfilerSimpleUDP.php', |
| 604 | + 'ProfilerStub' => 'includes/ProfilerStub.php', |
| 605 | + |
603 | 606 | # includes/search |
604 | 607 | 'MySQLSearchResultSet' => 'includes/search/SearchMySQL.php', |
605 | 608 | 'PostgresSearchResult' => 'includes/search/SearchPostgres.php', |