codec cleanup
[platform/upstream/boost-jam.git] / debug.c
1 /*
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)
5 */
6
7 #include "jam.h"
8
9 #include "hash.h"
10
11 #include <time.h>
12 #include <assert.h>
13
14
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 };
19
20
21 profile_frame * profile_init( char * rulename, profile_frame * frame )
22 {
23     if ( DEBUG_PROFILE ) profile_enter( rulename, frame );
24     return frame;
25 }
26
27
28 void profile_enter( char * rulename, profile_frame * frame )
29 {
30     if ( DEBUG_PROFILE )
31     {
32         clock_t start = clock();
33         profile_info info;
34         profile_info * p = &info;
35
36         if ( !rulename ) p = &profile_other;
37
38         if ( !profile_hash && rulename )
39             profile_hash = hashinit( sizeof( profile_info ), "profile" );
40
41         info.name = rulename;
42
43         if ( rulename && hashenter( profile_hash, (HASHDATA * *)&p ) )
44             p->cumulative = p->net = p->num_entries = p->stack_count = p->memory = 0;
45
46         ++p->num_entries;
47         ++p->stack_count;
48
49         frame->info = p;
50
51         frame->caller = profile_stack;
52         profile_stack = frame;
53
54         frame->entry_time = clock();
55         frame->overhead = 0;
56         frame->subrules = 0;
57
58         /* caller pays for the time it takes to play with the hash table */
59         if ( frame->caller )
60             frame->caller->overhead += frame->entry_time - start;
61     }
62 }
63
64
65 void profile_memory( long mem )
66 {
67     if ( DEBUG_PROFILE )
68         if ( profile_stack && profile_stack->info )
69             profile_stack->info->memory += mem;
70 }
71
72
73 void profile_exit( profile_frame * frame )
74 {
75     if ( DEBUG_PROFILE )
76     {
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
80          * this instance.
81          */
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.
85          */
86         frame->info->net += t - frame->subrules;
87
88         if ( frame->caller )
89         {
90             /* Caller's cumulative time must account for this overhead. */
91             frame->caller->overhead += frame->overhead;
92             frame->caller->subrules += t;
93         }
94         /* Pop this stack frame. */
95         --frame->info->stack_count;
96         profile_stack = frame->caller;
97     }
98 }
99
100
101 static void dump_profile_entry( void * p_, void * ignored )
102 {
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;
106     double net = p->net;
107     double q = p->net;
108     q /= ( p->num_entries ? p->num_entries : 1 );
109     cumulative /= CLOCKS_PER_SEC;
110     net /= CLOCKS_PER_SEC;
111     q /= CLOCKS_PER_SEC;
112     if ( !ignored )
113     {
114         profile_total.cumulative += p->net;
115         profile_total.memory += p->memory;
116     }
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 );
119 }
120
121
122 void profile_dump()
123 {
124     if ( profile_hash )
125     {
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 );
131     }
132 }