possible improve orc stability

mutex around calls to the orc compiler, check more error returns, use
limits from the orc headers
This commit is contained in:
John Cupitt 2015-12-08 14:57:48 +00:00
parent 3570f61f3d
commit a0ead35bbb
1 changed files with 36 additions and 11 deletions

View File

@ -60,12 +60,22 @@
#include <vips/vips.h>
#include <vips/vector.h>
#include <vips/internal.h>
#include <vips/thread.h>
/* 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*/