summaryrefslogtreecommitdiffstats
path: root/src/boost/tools/build/src/engine/debug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/tools/build/src/engine/debug.cpp')
-rw-r--r--src/boost/tools/build/src/engine/debug.cpp158
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;
+ }
+}