2001-05-07
2001-05-07 02:48:36 by Per Hedbor <ph@opera.com>
-
4717056777c90b95ecec96af203664c1df775dc1
(132 lines)
(+131/-1)
[
Show
| Annotate
]
Branch: 5.2
-DAVERAGE_PROFLING added. I needed a new macro, TRACE_ENTER and TRACE_LEAVE were very unsuited for the job. Currently just dumps the info to stdout now and then. Will be improved significantly later on.
Rev: server/base_server/configuration.pike:1.429
Rev: server/base_server/roxen.pike:1.664
Rev: server/etc/include/request_trace.h:1.5
1:
// A vitual server's main configuration
// Copyright © 1996 - 2000, Roxen IS.
- constant cvs_version = "$Id: configuration.pike,v 1.428 2001/05/03 17:26:41 per Exp $";
+ constant cvs_version = "$Id: configuration.pike,v 1.429 2001/05/07 02:48:33 per Exp $";
#include <module.h>
#include <module_constants.h>
#include <roxen.h>
32:
# define REQUEST_WERR(X)
#endif
+
+ #ifdef AVERAGE_PROFILING
+ class ProfStack
+ {
+ array current_stack = ({});
+
+ void enter( string k, RequestID id )
+ {
+ current_stack += ({ ({ k, gethrtime(), gethrvtime() }) });
+ }
+
+ void leave( string k, RequestID id )
+ {
+ int t0 = gethrtime();
+ int t1 = gethrvtime();
+
+ if( !sizeof(current_stack ) )
+ {
+ report_error("Popping out of profiling stack\n");
+ return;
+ }
+
+ int i = sizeof( current_stack )-1;
+ while( current_stack[ i ][0] != k && i >= 0 ) i--;
+
+ if(i < 0 )
+ {
+ report_error("Popping out of profiling stack, cannot find %O in %O\n",
+ k, current_stack);
+ return;
+ }
+
+ int tt = t0-current_stack[i][1];
+ int ttv = t1-current_stack[i][2];
+
+ if( i > 0 ) // Do not count child time in parent.
+ {
+ current_stack[i-1][1]+=tt+gethrtime()-t0;
+ current_stack[i-1][2]+=ttv+gethrvtime()-t1;
+ }
+ current_stack = current_stack[..i-1];
+ add_prof_entry( id, k, tt, ttv );
+ }
+ }
+
+ class ProfInfo( string url )
+ {
+ mapping data = ([]);
+ void add( string k, int h, int hrv )
+ {
+ if( !data[k] )
+ data[k] = ({ h, hrv, 1 });
+ else
+ {
+ data[k][0]+=h;
+ data[k][1]+=hrv;
+ data[k][2]++;
+ }
+ }
+
+ array summarize_table( )
+ {
+ array table = ({});
+ int n, t, v;
+ foreach( indices( data ), string k )
+ table += ({ ({ k,
+ sprintf( "%d", (n=data[k][2]) ),
+ sprintf("%5.2f",(t=data[k][0])/1000000.0),
+ sprintf("%5.2f", (v=data[k][1])/1000000.0),
+ sprintf("%8.2f", t/n/1000.0),
+ sprintf("%8.2f",v/n/1000.0), }) });
+ sort( (array(float))column(table,2), table );
+ return reverse(table);
+ }
+
+ void dump( )
+ {
+ write( "\n"+url+": \n" );
+ ADT.Table t = ADT.Table->table( summarize_table(),
+ ({ "What", "Calls",
+ "Time", "CPU",
+ "t/call(ms)", "cpu/call(ms)" }));
+
+ write( ADT.Table.ASCII.encode( t )+"\n" );
+
+ }
+ }
+
+ mapping profiling_info = ([]);
+
+ void debug_write_prof( )
+ {
+ foreach( sort( indices( profiling_info ) ), string p )
+ profiling_info[p]->dump();
+ }
+
+ void add_prof_entry( RequestID id, string k, int hr, int hrv )
+ {
+ if( !profiling_info[id->not_query] )
+ profiling_info[id->not_query] = ProfInfo(id->not_query);
+ profiling_info[id->not_query]->add( k, hr, hrv );
+ }
+
+ void avg_prof_enter( string name, string type, RequestID id )
+ {
+ if( !id->misc->prof_stack )
+ id->misc->prof_stack = ProfStack();
+ id->misc->prof_stack->enter( name+":"+type,id );
+ }
+ void avg_prof_leave( string name, string type, RequestID id )
+ {
+ if( !id->misc->prof_stack ) id->misc->prof_stack = ProfStack();
+ id->misc->prof_stack->leave( name+":"+type,id );
+ }
+ #endif
+
+
/* A configuration.. */
inherit Configuration;
inherit "basic_defvar";
1170:
if(find_internal)
{
TRACE_ENTER("Calling find_internal()...", find_internal);
+ PROF_ENTER("find_internal","location");
LOCK(find_internal);
fid=find_internal( rest, id );
UNLOCK();
TRACE_LEAVE(sprintf("find_internal has returned %O", fid));
-
+ PROF_LEAVE("find_internal","location");
if(fid)
{
if(mappingp(fid))
1226: Inside #if defined(URL_MODULES)
TIMER_START(url_modules);
foreach(url_module_cache||url_modules(), funp)
{
+ PROF_ENTER(Roxen.get_owning_module(funp)->module_name,"url module");
LOCK(funp);
TRACE_ENTER("URL module", funp);
tmp=funp( id, file );
UNLOCK();
-
+ PROF_LEAVE(Roxen.get_owning_module(funp)->module_name,"url module");
if(mappingp(tmp))
{
1285: Inside #if defined(MODULE_LEVEL_SECURITY)
return tmp2;
}
#endif
+ PROF_ENTER(Roxen.get_owning_module(tmp[1])->module_name,"location module");
TRACE_ENTER("Calling find_file()...", 0);
LOCK(tmp[1]);
fid=tmp[1]( file[ strlen(loc) .. ] + id->extra_extension, id);
UNLOCK();
TRACE_LEAVE("");
-
+ PROF_LEAVE(Roxen.get_owning_module(tmp[1])->module_name,"location module");
if(fid)
{
id->virtfile = loc;
1359:
TIMER_START(directory_module);
if(dir_module)
{
+ PROF_ENTER(dir_module->module_name,"directory module");
LOCK(dir_module);
TRACE_ENTER("Directory module", dir_module);
fid = dir_module->parse_directory(id);
UNLOCK();
-
+ PROF_LEAVE(dir_module->module_name,"directory module");
}
else
{
1400: Inside #if defined(MODULE_LEVEL_SECURITY)
return tmp;
}
#endif
+ PROF_ENTER(Roxen.get_owning_module(funp)->module_name,"ext module");
LOCK(funp);
tmp=funp(fid, loc, id);
UNLOCK();
-
+ PROF_LEAVE(Roxen.get_owning_module(funp)->module_name,"ext module");
if(tmp)
{
if(!objectp(tmp))
1511:
foreach(filter_module_cache||filter_modules(), tmp)
{
TRACE_ENTER("Filter module", tmp);
+ PROF_ENTER(Roxen.get_owning_module(tmp)->module_name,"filter");
if(res2=tmp(res,id))
{
if(res && res->file && (res2->file != res->file))
1519:
res=res2;
} else
TRACE_LEAVE("");
+ PROF_LEAVE(Roxen.get_owning_module(tmp)->module_name,"filter");
}
TIMER_END(filter_modules);