From a0ead35bbb8510ba00003ebc0c08eb004de6dfb9 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Tue, 8 Dec 2015 14:57:48 +0000 Subject: [PATCH] possible improve orc stability mutex around calls to the orc compiler, check more error returns, use limits from the orc headers --- libvips/iofuncs/vector.c | 47 ++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/libvips/iofuncs/vector.c b/libvips/iofuncs/vector.c index 9c579dfb..87a1f2ec 100644 --- a/libvips/iofuncs/vector.c +++ b/libvips/iofuncs/vector.c @@ -60,12 +60,22 @@ #include #include +#include +#include /* Cleared by the command-line --vips-novector switch and the IM_NOVECTOR env * var. */ gboolean vips__vector_enabled = TRUE; +void +vips_vector_error( VipsVector *vector ) +{ + if( vector->program ) + vips_warn( "VipsVector", "orc error: %s", + orc_program_get_error( vector->program ) ); +} + void vips_vector_init( void ) { @@ -168,6 +178,10 @@ vips_vector_new( const char *name, int dsize ) /* We always make d1, our callers make either a single point source, or * for area ops, a set of scanlines. + * + * Don't check error return. orc uses 0 to mean error, but the first + * var you create will have id 0 :-( The first var is unlikely to fail + * anyway. */ vector->d1 = orc_program_add_destination( vector->program, dsize, "d1" ); @@ -250,7 +264,9 @@ vips_vector_constant( VipsVector *vector, char *name, int value, int size ) printf( "orc_program_add_constant( %s, %d, %d, \"%s\" );\n", vector->unique_name, size, value, name ); #endif /*DEBUG_TRACE*/ - orc_program_add_constant( vector->program, size, value, name ); + if( !orc_program_add_constant( vector->program, + size, value, name ) ) + vips_vector_error( vector ); vector->n_constant += 1; } #endif /*HAVE_ORC*/ @@ -264,8 +280,9 @@ vips_vector_source_name( VipsVector *vector, char *name, int size ) #ifdef HAVE_ORC g_assert( orc_program_find_var_by_name( vector->program, name ) == -1 ); - vector->s[vector->n_source] = var = - orc_program_add_source( vector->program, size, name ); + if( !(var = orc_program_add_source( vector->program, size, name )) ) + vips_vector_error( vector ); + vector->s[vector->n_source] = var; #ifdef DEBUG_TRACE printf( "orc_program_add_source( %s, %d, \"%s\" );\n", vector->unique_name, size, name ); @@ -288,7 +305,9 @@ vips_vector_source_scanline( VipsVector *vector, if( orc_program_find_var_by_name( vector->program, name ) == -1 ) { int var; - var = orc_program_add_source( vector->program, size, name ); + if( !(var = orc_program_add_source( vector->program, + size, name )) ) + vips_vector_error( vector ); #ifdef DEBUG_TRACE printf( "orc_program_add_source( %s, %d, \"%s\" );\n", vector->unique_name, size, name ); @@ -306,7 +325,9 @@ vips_vector_temporary( VipsVector *vector, char *name, int size ) #ifdef HAVE_ORC g_assert( orc_program_find_var_by_name( vector->program, name ) == -1 ); - orc_program_add_temporary( vector->program, size, name ); + if( !orc_program_add_temporary( vector->program, size, name ) ) + vips_vector_error( vector ); + #ifdef DEBUG_TRACE printf( "orc_program_add_temporary( %s, %d, \"%s\" );\n", vector->unique_name, size, name ); @@ -321,20 +342,19 @@ vips_vector_full( VipsVector *vector ) /* We can need a max of 2 constants plus one source per * coefficient, so stop if we're sure we don't have enough. */ - if( vector->n_constant > 16 - 2 ) + if( vector->n_constant > ORC_MAX_CONST_VARS - 2 ) return( TRUE ); /* You can have 8 parameters, and d1 counts as one of them, so +1 * there. */ - if( vector->n_source + vector->n_scanline + 1 > 7 ) + if( vector->n_source + vector->n_scanline + 1 > ORC_MAX_PARAM_VARS ) return( TRUE ); - /* I seem to get segvs with I counts over about 50 :-( argh. After - * signalling full, some operations will add up to 4 more instructions - * as they finish up. Leave a margin. + /* After signalling full, some operations will add up to 4 more + * instructions as they finish up. Leave a margin. */ - if( vector->n_instruction > 42 ) + if( vector->n_instruction + 10 > ORC_N_INSNS ) return( TRUE ); return( FALSE ); @@ -346,7 +366,12 @@ vips_vector_compile( VipsVector *vector ) #ifdef HAVE_ORC OrcCompileResult result; + /* Some orcs seem to be unstable with many compilers active at once. + */ + g_mutex_lock( vips__global_lock ); result = orc_program_compile( vector->program ); + g_mutex_unlock( vips__global_lock ); + #ifdef DEBUG_TRACE printf( "orc_program_compile( %s );\n", vector->unique_name ); #endif /*DEBUG_TRACE*/