2 Copyright Rene Rivera 2005.
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
15 static profile_frame * profile_stack = 0;
16 static struct hash * profile_hash = 0;
17 static profile_info profile_other = { "[OTHER]", 0, 0, 0, 0, 0 };
18 static profile_info profile_total = { "[TOTAL]", 0, 0, 0, 0, 0 };
21 profile_frame * profile_init( char * rulename, profile_frame * frame )
23 if ( DEBUG_PROFILE ) profile_enter( rulename, frame );
28 void profile_enter( char * rulename, profile_frame * frame )
32 clock_t start = clock();
34 profile_info * p = &info;
36 if ( !rulename ) p = &profile_other;
38 if ( !profile_hash && rulename )
39 profile_hash = hashinit( sizeof( profile_info ), "profile" );
43 if ( rulename && hashenter( profile_hash, (HASHDATA * *)&p ) )
44 p->cumulative = p->net = p->num_entries = p->stack_count = p->memory = 0;
51 frame->caller = profile_stack;
52 profile_stack = frame;
54 frame->entry_time = clock();
58 /* caller pays for the time it takes to play with the hash table */
60 frame->caller->overhead += frame->entry_time - start;
65 void profile_memory( long mem )
68 if ( profile_stack && profile_stack->info )
69 profile_stack->info->memory += mem;
73 void profile_exit( profile_frame * frame )
77 /* Cumulative time for this call. */
78 clock_t t = clock() - frame->entry_time - frame->overhead;
79 /* If this rule is already present on the stack, don't add the time for
82 if ( frame->info->stack_count == 1 )
83 frame->info->cumulative += t;
84 /* Net time does not depend on presense of the same rule in call stack.
86 frame->info->net += t - frame->subrules;
90 /* Caller's cumulative time must account for this overhead. */
91 frame->caller->overhead += frame->overhead;
92 frame->caller->subrules += t;
94 /* Pop this stack frame. */
95 --frame->info->stack_count;
96 profile_stack = frame->caller;
101 static void dump_profile_entry( void * p_, void * ignored )
103 profile_info * p = (profile_info *)p_;
104 unsigned long mem_each = ( p->memory / ( p->num_entries ? p->num_entries : 1 ) );
105 double cumulative = p->cumulative;
108 q /= ( p->num_entries ? p->num_entries : 1 );
109 cumulative /= CLOCKS_PER_SEC;
110 net /= CLOCKS_PER_SEC;
114 profile_total.cumulative += p->net;
115 profile_total.memory += p->memory;
117 printf( "%10ld %12.6f %12.6f %12.8f %10ld %10ld %s\n", p->num_entries,
118 cumulative, net, q, p->memory, mem_each, p->name );
126 printf( "%10s %12s %12s %12s %10s %10s %s\n", "--count--", "--gross--",
127 "--net--", "--each--", "--mem--", "--each--", "--name--" );
128 hashenumerate( profile_hash, dump_profile_entry, 0 );
129 dump_profile_entry( &profile_other, 0 );
130 dump_profile_entry( &profile_total, (void *)1 );