diff options
author | Patrick Simianer <simianer@cl.uni-heidelberg.de> | 2012-05-13 03:35:30 +0200 |
---|---|---|
committer | Patrick Simianer <simianer@cl.uni-heidelberg.de> | 2012-05-13 03:35:30 +0200 |
commit | d94373453c69c6cfec952a0f7b427cacc78654d8 (patch) | |
tree | 43febdf719c103d19bd5d22d0be734e1574bc1e9 /jam-files/engine/debug.c | |
parent | cc9650b8b664d1f6836a0fa86a012401b51aafa0 (diff) | |
parent | a65a80c5d5b6fc4cbd32280f07cae9be71551b70 (diff) |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'jam-files/engine/debug.c')
-rw-r--r-- | jam-files/engine/debug.c | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/jam-files/engine/debug.c b/jam-files/engine/debug.c new file mode 100644 index 00000000..7290555a --- /dev/null +++ b/jam-files/engine/debug.c @@ -0,0 +1,132 @@ +/* + Copyright Rene Rivera 2005. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +#include "jam.h" + +#include "hash.h" + +#include <time.h> +#include <assert.h> + + +static profile_frame * profile_stack = 0; +static struct hash * profile_hash = 0; +static profile_info profile_other = { "[OTHER]", 0, 0, 0, 0, 0 }; +static profile_info profile_total = { "[TOTAL]", 0, 0, 0, 0, 0 }; + + +profile_frame * profile_init( char * rulename, profile_frame * frame ) +{ + if ( DEBUG_PROFILE ) profile_enter( rulename, frame ); + return frame; +} + + +void profile_enter( char * rulename, profile_frame * frame ) +{ + if ( DEBUG_PROFILE ) + { + clock_t start = clock(); + profile_info info; + profile_info * p = &info; + + if ( !rulename ) p = &profile_other; + + if ( !profile_hash && rulename ) + profile_hash = hashinit( sizeof( profile_info ), "profile" ); + + info.name = rulename; + + if ( rulename && hashenter( profile_hash, (HASHDATA * *)&p ) ) + p->cumulative = p->net = p->num_entries = p->stack_count = p->memory = 0; + + ++p->num_entries; + ++p->stack_count; + + frame->info = p; + + frame->caller = profile_stack; + profile_stack = frame; + + frame->entry_time = clock(); + frame->overhead = 0; + frame->subrules = 0; + + /* caller pays for the time it takes to play with the hash table */ + if ( frame->caller ) + frame->caller->overhead += frame->entry_time - start; + } +} + + +void profile_memory( long mem ) +{ + if ( DEBUG_PROFILE ) + if ( profile_stack && profile_stack->info ) + profile_stack->info->memory += mem; +} + + +void profile_exit( profile_frame * frame ) +{ + if ( DEBUG_PROFILE ) + { + /* Cumulative time for this call. */ + clock_t t = clock() - frame->entry_time - frame->overhead; + /* If this rule is already present on the stack, don't add the time for + * this instance. + */ + if ( frame->info->stack_count == 1 ) + frame->info->cumulative += t; + /* Net time does not depend on presense of the same rule in call stack. + */ + frame->info->net += t - frame->subrules; + + if ( frame->caller ) + { + /* Caller's cumulative time must account for this overhead. */ + frame->caller->overhead += frame->overhead; + frame->caller->subrules += t; + } + /* Pop this stack frame. */ + --frame->info->stack_count; + profile_stack = frame->caller; + } +} + + +static void dump_profile_entry( void * p_, void * ignored ) +{ + profile_info * p = (profile_info *)p_; + unsigned long mem_each = ( p->memory / ( p->num_entries ? p->num_entries : 1 ) ); + double cumulative = p->cumulative; + double net = p->net; + double q = p->net; + q /= ( p->num_entries ? p->num_entries : 1 ); + cumulative /= CLOCKS_PER_SEC; + net /= CLOCKS_PER_SEC; + q /= CLOCKS_PER_SEC; + if ( !ignored ) + { + profile_total.cumulative += p->net; + profile_total.memory += p->memory; + } + printf( "%10ld %12.6f %12.6f %12.8f %10ld %10ld %s\n", p->num_entries, + cumulative, net, q, p->memory, mem_each, p->name ); +} + + +void profile_dump() +{ + if ( profile_hash ) + { + printf( "%10s %12s %12s %12s %10s %10s %s\n", "--count--", "--gross--", + "--net--", "--each--", "--mem--", "--each--", "--name--" ); + hashenumerate( profile_hash, dump_profile_entry, 0 ); + dump_profile_entry( &profile_other, 0 ); + dump_profile_entry( &profile_total, (void *)1 ); + } +} |