try reading ahead to cache rather than stalling

This commit is contained in:
John Cupitt 2012-08-24 13:55:08 +01:00
parent 39b05f5172
commit 4bb3eba029
1 changed files with 16 additions and 22 deletions

View File

@ -109,50 +109,44 @@ vips_sequential_generate( VipsRegion *or,
vips_diag( "VipsSequential", vips_diag( "VipsSequential",
"request for %d lines, starting at line %d", "request for %d lines, starting at line %d",
r->height, r->top ); r->height, r->top );
retry:
g_mutex_lock( sequential->lock ); g_mutex_lock( sequential->lock );
VIPS_DEBUG_MSG( "thread %p has lock ...\n", g_thread_self() ); VIPS_DEBUG_MSG( "thread %p has lock ...\n", g_thread_self() );
if( r->top > sequential->y_pos ) { if( r->top > sequential->y_pos ) {
/* This is for stuff in the future, stall. VipsRect area;
/* This is for stuff in the future, read from the current
* point to the start of this new chunk.
*/ */
VIPS_DEBUG_MSG( "thread %p stalling ...\n", g_thread_self() ); area.left = 0;
g_cond_wait( sequential->ready, sequential->lock ); area.top = sequential->y_pos;
VIPS_DEBUG_MSG( "thread %p awake again, retrying ...\n", area.width = 1;
g_thread_self() ); area.height = r->top - sequential->y_pos;
g_mutex_unlock( sequential->lock );
goto retry; if( vips_region_prepare( ir, &area ) ) {
g_mutex_unlock( sequential->lock );
return( -1 );
}
sequential->y_pos = VIPS_RECT_BOTTOM( &area );
} }
/* This is a request for old or present pixels -- serve from cache. /* This is a request for old or present pixels -- serve from cache.
* This may trigger further, sequential reads. * This may trigger further reads.
*/ */
VIPS_DEBUG_MSG( "thread %p reading ...\n", g_thread_self() );
if( vips_region_prepare( ir, r ) || if( vips_region_prepare( ir, r ) ||
vips_region_region( or, ir, r, r->left, r->top ) ) { vips_region_region( or, ir, r, r->left, r->top ) ) {
VIPS_DEBUG_MSG( "thread %p unlocking ...\n", g_thread_self() );
g_mutex_unlock( sequential->lock ); g_mutex_unlock( sequential->lock );
return( -1 ); return( -1 );
} }
if( VIPS_RECT_BOTTOM( r ) > sequential->y_pos ) { if( VIPS_RECT_BOTTOM( r ) > sequential->y_pos ) {
/* This request has moved the read point. Update it, and wake
* up all stalled threads for a retry.
*/
sequential->y_pos = VIPS_RECT_BOTTOM( r ); sequential->y_pos = VIPS_RECT_BOTTOM( r );
VIPS_DEBUG_MSG( "thread %p updating y_pos to %d and "
"waking stalled\n",
g_thread_self(),
sequential->y_pos );
g_cond_broadcast( sequential->ready );
} }
VIPS_DEBUG_MSG( "thread %p unlocking ...\n", g_thread_self() );
g_mutex_unlock( sequential->lock ); g_mutex_unlock( sequential->lock );
return( 0 ); return( 0 );