From 3a195d4d5c7afb119ff9674f49f1e3a9968bd06d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 26 Nov 2013 13:01:40 +0000 Subject: [PATCH] support main thread gates --- libvips/iofuncs/gate.c | 54 +++++++++++++++++++++++++++++------------- libvips/iofuncs/init.c | 18 ++++++++++++-- tools/vipsprofile.py | 5 ++-- 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/libvips/iofuncs/gate.c b/libvips/iofuncs/gate.c index ca52da4d..eadf10a0 100644 --- a/libvips/iofuncs/gate.c +++ b/libvips/iofuncs/gate.c @@ -41,6 +41,7 @@ #include #include +#include #define VIPS_GATE_SIZE (1000) @@ -103,13 +104,24 @@ vips_thread_profile_save_gate( VipsObject *key, VipsObject *value, FILE *fp ) } static void -vips_thread_profile_save( VipsThreadProfile *profile, FILE *fp ) +vips_thread_profile_save( VipsThreadProfile *profile ) { g_mutex_lock( vips__global_lock ); - fprintf( fp, "thread: %s (%p)\n", profile->name, profile ); + VIPS_DEBUG_MSG( "vips_thread_profile_save: %s\n", profile->name ); + + if( !vips__thread_fp ) { + vips__thread_fp = + vips__file_open_write( "vips-profile.txt", TRUE ); + if( !vips__thread_fp ) + vips_error_exit( "unable to create profile log" ); + + printf( "recording profile in vips-profile.txt\n" ); + } + + fprintf( vips__thread_fp, "thread: %s (%p)\n", profile->name, profile ); g_hash_table_foreach( profile->gates, - (GHFunc) vips_thread_profile_save_gate, fp ); + (GHFunc) vips_thread_profile_save_gate, vips__thread_fp ); g_mutex_unlock( vips__global_lock ); } @@ -117,8 +129,10 @@ vips_thread_profile_save( VipsThreadProfile *profile, FILE *fp ) static void vips_thread_profile_free( VipsThreadProfile *profile ) { - if( vips__thread_fp ) - vips_thread_profile_save( profile, vips__thread_fp ); + VIPS_DEBUG_MSG( "vips_thread_profile_free: %s\n", profile->name ); + + if( vips__thread_profile ) + vips_thread_profile_save( profile ); VIPS_FREEF( g_hash_table_destroy, profile->gates ); VIPS_FREE( profile ); @@ -159,14 +173,6 @@ vips__thread_profile_init( void ) vips_thread_profile_key = g_private_new( (GDestroyNotify) vips_thread_profile_free ); #endif - - if( vips__thread_profile ) { - if( !(vips__thread_fp = - vips__file_open_write( "vips-profile.txt", TRUE )) ) - vips_error_exit( "unable to create profile log" ); - - printf( "recording profile in vips-profile.txt\n" ); - } } void @@ -178,6 +184,8 @@ vips__thread_profile_attach( const char *thread_name ) g_once( &once, (GThreadFunc) vips__thread_profile_init, NULL ); + VIPS_DEBUG_MSG( "vips__thread_profile_attach: %s\n", thread_name ); + g_assert( !g_private_get( vips_thread_profile_key ) ); profile = g_new( VipsThreadProfile, 1 ); @@ -205,8 +213,10 @@ vips__thread_profile_detach( void ) { VipsThreadProfile *profile; - if( (profile = vips_thread_profile_get()) ) + if( (profile = vips_thread_profile_get()) ) { vips_thread_profile_free( profile ); + g_private_set( vips_thread_profile_key, NULL ); + } } static VipsThreadGate * @@ -251,7 +261,11 @@ vips__thread_gate_start( const char *gate_name ) { VipsThreadProfile *profile; + VIPS_DEBUG_MSG( "vips__thread_gate_start: %s\n", gate_name ); + if( (profile = vips_thread_profile_get()) ) { + gint64 time = vips_get_time(); + VipsThreadGate *gate; if( !(gate = @@ -264,7 +278,9 @@ vips__thread_gate_start( const char *gate_name ) if( gate->start->i >= VIPS_GATE_SIZE ) vips_thread_gate_block_add( &gate->start ); - gate->start->time[gate->start->i++] = vips_get_time(); + gate->start->time[gate->start->i++] = time; + + VIPS_DEBUG_MSG( "\t %" G_GINT64_FORMAT "\n", time ); } } @@ -273,7 +289,11 @@ vips__thread_gate_stop( const char *gate_name ) { VipsThreadProfile *profile; + VIPS_DEBUG_MSG( "vips__thread_gate_stop: %s\n", gate_name ); + if( (profile = vips_thread_profile_get()) ) { + gint64 time = vips_get_time(); + VipsThreadGate *gate; if( !(gate = @@ -286,6 +306,8 @@ vips__thread_gate_stop( const char *gate_name ) if( gate->stop->i >= VIPS_GATE_SIZE ) vips_thread_gate_block_add( &gate->stop ); - gate->stop->time[gate->stop->i++] = vips_get_time(); + gate->stop->time[gate->stop->i++] = time; + + VIPS_DEBUG_MSG( "\t %" G_GINT64_FORMAT "\n", time ); } } diff --git a/libvips/iofuncs/init.c b/libvips/iofuncs/init.c index 77c70b98..a923aba1 100644 --- a/libvips/iofuncs/init.c +++ b/libvips/iofuncs/init.c @@ -220,7 +220,12 @@ vips__init( const char *argv0 ) g_free( prgname ); vips__thread_profile_attach( "main" ); - VIPS_GATE_START( "main" ); + + /* We can't do VIPS_GATE_START() until command-line processing + * happens, since vips__thread_profile may not be set yet. Call + * directly. + */ + vips__thread_gate_start( "main" ); /* Try to discover our prefix. */ @@ -377,8 +382,17 @@ vips_shutdown( void ) im_close_plugins(); - VIPS_GATE_STOP( "main" ); + /* Mustn't run this more than once. + */ +{ + static gboolean done = FALSE; + + if( !done ) + VIPS_GATE_STOP( "main" ); +} + vips__thread_profile_detach(); + vips__thread_profile_stop(); /* In dev releases, always show leaks. But not more than once, it's * annoying. diff --git a/tools/vipsprofile.py b/tools/vipsprofile.py index f2c86b93..a1e02e7f 100755 --- a/tools/vipsprofile.py +++ b/tools/vipsprofile.py @@ -61,7 +61,6 @@ class Event: thread.events.append(self) - input_filename = 'vips-profile.txt' thread_id = 0 @@ -217,7 +216,7 @@ def draw_event(ctx, event): ctx.move_to(left + width / 2 - twidth / 2, top + theight) ctx.set_source_rgb(1.00, 0.83, 0.00) ctx.show_text(event.gate_name) - ctx.stroke() + #ctx.stroke() for thread in threads: xbearing, ybearing, twidth, theight, xadvance, yadvance = \ @@ -225,7 +224,7 @@ for thread in threads: ctx.move_to(0, theight + thread.total_y * PIXELS_PER_GATE) ctx.set_source_rgb(1.00, 1.00, 1.00) ctx.show_text(thread.thread_name) - ctx.stroke() + #ctx.stroke() for event in thread.events: draw_event(ctx, event)