diff options
Diffstat (limited to 'src/boost/tools/build/src/engine/debug.cpp')
-rw-r--r-- | src/boost/tools/build/src/engine/debug.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/boost/tools/build/src/engine/debug.cpp b/src/boost/tools/build/src/engine/debug.cpp new file mode 100644 index 000000000..f802b8a00 --- /dev/null +++ b/src/boost/tools/build/src/engine/debug.cpp @@ -0,0 +1,158 @@ +/* + * Copyright 2005, 2016. Rene Rivera + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at + * https://www.bfgroup.xyz/b2/LICENSE.txt) + */ + +#include "jam.h" +#include "debug.h" +#include "output.h" +#include "hash.h" +#include <time.h> + + +static profile_frame * profile_stack = 0; +static struct hash * profile_hash = 0; +static profile_info profile_other = { 0 }; +static profile_info profile_total = { 0 }; + + +profile_frame * profile_init( OBJECT * rulename, profile_frame * frame ) +{ + if ( DEBUG_PROFILE ) profile_enter( rulename, frame ); + return frame; +} + + +void profile_enter( OBJECT * rulename, profile_frame * frame ) +{ + if ( DEBUG_PROFILE ) + { + double start = profile_clock(); + profile_info * p; + + if ( !profile_hash && rulename ) + profile_hash = hashinit( sizeof( profile_info ), "profile" ); + + if ( rulename ) + { + int found; + p = (profile_info *)hash_insert( profile_hash, rulename, &found ); + if ( !found ) + { + p->name = rulename; + p->cumulative = 0; + p->net = 0; + p->num_entries = 0; + p->stack_count = 0; + p->memory = 0; + } + } + else + { + p = &profile_other; + } + + p->num_entries += 1; + p->stack_count += 1; + + frame->info = p; + + frame->caller = profile_stack; + profile_stack = frame; + + frame->entry_time = profile_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( size_t mem ) +{ + if ( DEBUG_PROFILE ) + if ( profile_stack && profile_stack->info ) + profile_stack->info->memory += ((double)mem) / 1024; +} + + +void profile_exit( profile_frame * frame ) +{ + if ( DEBUG_PROFILE ) + { + /* Cumulative time for this call. */ + double t = profile_clock() - frame->entry_time - frame->overhead; + /* If this rule is already present on the stack, do not add the time for + * this instance. + */ + if ( frame->info->stack_count == 1 ) + frame->info->cumulative += t; + /* Net time does not depend on presence 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_; + double mem_each = ( p->memory / ( p->num_entries ? p->num_entries : 1 + ) ); + double q = p->net; + if (p->num_entries) q /= p->num_entries; + if ( !ignored ) + { + profile_total.cumulative += p->net; + profile_total.memory += p->memory; + } + out_printf( "%10ld %12.6f %12.6f %12.8f %10.2f %10.2f %s\n", p->num_entries, + p->cumulative, p->net, q, p->memory, mem_each, object_str( p->name ) ); +} + + +void profile_dump() +{ + if ( profile_hash ) + { + out_printf( "%10s %12s %12s %12s %10s %10s %s\n", "--count--", "--gross--", + "--net--", "--each--", "--mem--", "--each--", "--name--" ); + hashenumerate( profile_hash, dump_profile_entry, 0 ); + profile_other.name = constant_other; + dump_profile_entry( &profile_other, 0 ); + profile_total.name = constant_total; + dump_profile_entry( &profile_total, (void *)1 ); + } +} + +double profile_clock() +{ + return ((double) clock()) / CLOCKS_PER_SEC; +} + +OBJECT * profile_make_local( char const * scope ) +{ + if ( DEBUG_PROFILE ) + { + return object_new( scope ); + } + else + { + return 0; + } +} |