Skip to content

Commit

Permalink
Simple threading change (~4% faster). Breaks pause/resume for now
Browse files Browse the repository at this point in the history
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@40 b64f7644-9d1e-0410-96f1-a4d463321fa5
  • Loading branch information
titer committed Mar 18, 2006
1 parent 0531e62 commit 111307f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 140 deletions.
7 changes: 4 additions & 3 deletions libhb/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ struct hb_work_object_s
int id;
char * name;

#ifdef __LIBHB__
int (* init) ( hb_work_object_t *, hb_job_t * );
int (* work) ( hb_work_object_t *, hb_buffer_t **,
hb_buffer_t ** );
Expand All @@ -333,11 +334,11 @@ struct hb_work_object_s

hb_work_private_t * private_data;

hb_lock_t * lock;
int used;
uint64_t time;
hb_thread_t * thread;
volatile int * done;

hb_work_object_t * next;
#endif
};

extern hb_work_object_t hb_sync;
Expand Down
182 changes: 45 additions & 137 deletions libhb/work.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ typedef struct

static void work_func();
static void do_job( hb_job_t *, int cpu_count );
static void job_loop( void * );
static void work_loop( void * );

hb_thread_t * hb_work_init( hb_list_t * jobs, int cpu_count,
volatile int * die, int * error )
Expand Down Expand Up @@ -68,9 +68,7 @@ static void do_job( hb_job_t * job, int cpu_count )
{
hb_title_t * title;
int i;
hb_thread_t * threads[8];
hb_work_object_t * w;
uint64_t time_total;
hb_audio_t * audio;
hb_subtitle_t * subtitle;

Expand Down Expand Up @@ -219,69 +217,52 @@ static void do_job( hb_job_t * job, int cpu_count )
hb_log( " + output: %s", job->file );
job->muxer = hb_muxer_init( job );

for( i = 0; i < hb_list_count( job->list_work ); i++ )
job->done = 0;

/* Launch processing threads */
for( i = 1; i < hb_list_count( job->list_work ); i++ )
{
w = hb_list_item( job->list_work, i );
w->lock = hb_lock_init();
w->used = 0;
w->time = 0;
w = hb_list_item( job->list_work, i );
w->done = &job->done;
w->init( w, job );
w->thread = hb_thread_init( w->name, work_loop, w,
HB_LOW_PRIORITY );
}

job->done = 0;

/* Launch processing threads */
for( i = 0; i < cpu_count; i++ )
int done = 0;
w = hb_list_item( job->list_work, 0 );
w->init( w, job );
while( !*job->die )
{
char thread_name[16];
if( cpu_count - 1 )
if( w->work( w, NULL, NULL ) == HB_WORK_DONE )
{
snprintf( thread_name, 16, "cpu killer %d", i + 1 );
done = 1;
}
else
if( done &&
!hb_fifo_size( job->fifo_sync ) &&
!hb_fifo_size( job->fifo_render ) &&
hb_fifo_size( job->fifo_mpeg4 ) < 2 )
{
snprintf( thread_name, 16, "cpu killer" );
break;
}
threads[i] = hb_thread_init( thread_name, job_loop, job,
HB_LOW_PRIORITY );
}

while( !*job->die && !job->done )
{
hb_snooze( 500 );
}

for( i = 0; i < cpu_count; i++ )
{
hb_thread_close( &threads[i] );
}

/* Stop read & write threads */
hb_thread_close( &job->reader );
hb_thread_close( &job->muxer );

/* Stats */
time_total = 0;
for( i = 0; i < hb_list_count( job->list_work ); i++ )
{
w = hb_list_item( job->list_work, i );
time_total += w->time;
}
for( i = 0; i < hb_list_count( job->list_work ); i++ )
{
w = hb_list_item( job->list_work, i );
hb_log( "%s: %.2f %%", w->name,
100.0 * (float) w->time / (float) time_total );
hb_snooze( 50 );
}
hb_list_rem( job->list_work, w );
w->close( w );
job->done = 1;

/* Close work objects */
while( ( w = hb_list_item( job->list_work, 0 ) ) )
{
hb_list_rem( job->list_work, w );
hb_lock_close( &w->lock );
hb_thread_close( &w->thread );
w->close( w );
}

/* Stop read & write threads */
hb_thread_close( &job->reader );
hb_thread_close( &job->muxer );

/* Close fifos */
hb_fifo_close( &job->fifo_mpeg2 );
hb_fifo_close( &job->fifo_raw );
Expand All @@ -303,105 +284,32 @@ static void do_job( hb_job_t * job, int cpu_count )
}
}

static int lock( hb_work_object_t * w )
{
hb_lock( w->lock );
if( w->used )
{
hb_unlock( w->lock );
return 0;
}
w->used = 1;
hb_unlock( w->lock );
return 1;
}

static void unlock( hb_work_object_t * w )
{
hb_lock( w->lock );
w->used = 0;
hb_unlock( w->lock );
}

static void job_loop( void * _job )
static void work_loop( void * _w )
{
hb_job_t * job = _job;
hb_work_object_t * w = _w;
hb_buffer_t * buf_in, * buf_out;
hb_work_object_t * w;
int work_count;
int act;
int i;
uint64_t date;
int done;

work_count = hb_list_count( job->list_work );
act = 0;
done = 0;

while( !*job->die && !job->done )
while( !*w->done )
{
/* Handle synchronization, resampling, framerate change,
etc */
w = hb_list_item( job->list_work, 0 );
if( lock( w ) )
#if 0
hb_lock( job->pause );
hb_unlock( job->pause );
#endif
if( hb_fifo_is_full( w->fifo_out ) ||
!( buf_in = hb_fifo_get( w->fifo_in ) ) )
{
date = hb_get_date();
if( w->work( w, NULL, NULL ) == HB_WORK_DONE )
{
done = 1;
}
w->time += hb_get_date() - date;
unlock( w );
hb_snooze( 50 );
continue;
}

for( i = 1; !*job->die && !job->done && i < work_count; i++ )
w->work( w, &buf_in, &buf_out );
if( buf_in )
{
w = hb_list_item( job->list_work, i );
if( !lock( w ) )
continue;

for( ;; )
{
hb_lock( job->pause );
hb_unlock( job->pause );

if( hb_fifo_is_full( w->fifo_out ) ||
!( buf_in = hb_fifo_get( w->fifo_in ) ) )
{
break;
}

date = hb_get_date();
w->work( w, &buf_in, &buf_out );
w->time += hb_get_date() - date;
if( buf_in )
{
hb_buffer_close( &buf_in );
}
if( buf_out )
{
act = 1;
hb_fifo_push( w->fifo_out, buf_out );
}
}

unlock( w );
hb_buffer_close( &buf_in );
}

if( done &&
!hb_fifo_size( job->fifo_sync ) &&
!hb_fifo_size( job->fifo_render ) &&
hb_fifo_size( job->fifo_mpeg4 ) < 2 )
{
job->done = 1;
break;
}

/* If we did nothing, wait a bit before trying again */
if( !act )
if( buf_out )
{
hb_snooze( 50 );
hb_fifo_push( w->fifo_out, buf_out );
}
act = 0;
}
}

0 comments on commit 111307f

Please sign in to comment.