X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Ffifo.c;h=a29e84696f453bb49a7160c21b89377468ba6185;hb=4b72a63eb61a01275493c4bfb51ba02152d1c5e1;hp=7337874bfe9673d22fea41f6e1d1b09cf9ebca97;hpb=e2cd98f3e71232b518b7165705d25d965ab9d9f3;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/fifo.c b/libhb/fifo.c index 7337874b..a29e8469 100644 --- a/libhb/fifo.c +++ b/libhb/fifo.c @@ -10,11 +10,18 @@ #include #endif +#define FIFO_TIMEOUT 200 + /* Fifo */ struct hb_fifo_s { hb_lock_t * lock; + hb_cond_t * cond_full; + int wait_full; + hb_cond_t * cond_empty; + int wait_empty; uint32_t capacity; + uint32_t thresh; uint32_t size; uint32_t buffer_size; hb_buffer_t * first; @@ -51,7 +58,7 @@ void hb_buffer_pool_init( void ) int i; for ( i = 10; i < 26; ++i ) { - buffers.pool[i] = hb_fifo_init(BUFFER_POOL_MAX_ELEMENTS); + buffers.pool[i] = hb_fifo_init(BUFFER_POOL_MAX_ELEMENTS, 1); buffers.pool[i]->buffer_size = 1 << i; } /* requests smaller than 2^10 are satisfied from the 2^10 pool. */ @@ -90,8 +97,8 @@ void hb_buffer_pool_free( void ) } } - hb_deep_log( 2, "Allocated %lld bytes of buffers on this pass and Freed %lld bytes, " - "%lld bytes leaked", buffers.allocated, freed, buffers.allocated - freed); + hb_deep_log( 2, "Allocated %"PRId64" bytes of buffers on this pass and Freed %"PRId64" bytes, " + "%"PRId64" bytes leaked", buffers.allocated, freed, buffers.allocated - freed); buffers.allocated = 0; hb_unlock(buffers.lock); } @@ -195,14 +202,19 @@ void hb_buffer_close( hb_buffer_t ** _b ) return; } /* either the pool is full or this size doesn't use a pool - free the buf */ - if( b->data ) + while( b ) { - free( b->data ); - hb_lock(buffers.lock); - buffers.allocated -= b->alloc; - hb_unlock(buffers.lock); + hb_buffer_t * next = b->next; + if( b->data ) + { + free( b->data ); + hb_lock(buffers.lock); + buffers.allocated -= b->alloc; + hb_unlock(buffers.lock); + } + free( b ); + b = next; } - free( b ); *_b = NULL; } @@ -215,16 +227,36 @@ void hb_buffer_copy_settings( hb_buffer_t * dst, const hb_buffer_t * src ) dst->flags = src->flags; } -hb_fifo_t * hb_fifo_init( int capacity ) +hb_fifo_t * hb_fifo_init( int capacity, int thresh ) { hb_fifo_t * f; - f = calloc( sizeof( hb_fifo_t ), 1 ); - f->lock = hb_lock_init(); - f->capacity = capacity; + f = calloc( sizeof( hb_fifo_t ), 1 ); + f->lock = hb_lock_init(); + f->cond_full = hb_cond_init(); + f->cond_empty = hb_cond_init(); + f->capacity = capacity; + f->thresh = thresh; f->buffer_size = 0; return f; } +int hb_fifo_size_bytes( hb_fifo_t * f ) +{ + int ret = 0; + hb_buffer_t * link; + + hb_lock( f->lock ); + link = f->first; + while ( link ) + { + ret += link->size; + link = link->next; + } + hb_unlock( f->lock ); + + return ret; +} + int hb_fifo_size( hb_fifo_t * f ) { int ret; @@ -258,6 +290,35 @@ float hb_fifo_percent_full( hb_fifo_t * f ) return ret; } +hb_buffer_t * hb_fifo_get_wait( hb_fifo_t * f ) +{ + hb_buffer_t * b; + + hb_lock( f->lock ); + if( f->size < 1 ) + { + f->wait_empty = 1; + hb_cond_timedwait( f->cond_empty, f->lock, FIFO_TIMEOUT ); + if( f->size < 1 ) + { + hb_unlock( f->lock ); + return NULL; + } + } + b = f->first; + f->first = b->next; + b->next = NULL; + f->size -= 1; + if( f->wait_full && f->size == f->capacity - f->thresh ) + { + f->wait_full = 0; + hb_cond_signal( f->cond_full ); + } + hb_unlock( f->lock ); + + return b; +} + hb_buffer_t * hb_fifo_get( hb_fifo_t * f ) { hb_buffer_t * b; @@ -272,6 +333,32 @@ hb_buffer_t * hb_fifo_get( hb_fifo_t * f ) f->first = b->next; b->next = NULL; f->size -= 1; + if( f->wait_full && f->size == f->capacity - f->thresh ) + { + f->wait_full = 0; + hb_cond_signal( f->cond_full ); + } + hb_unlock( f->lock ); + + return b; +} + +hb_buffer_t * hb_fifo_see_wait( hb_fifo_t * f ) +{ + hb_buffer_t * b; + + hb_lock( f->lock ); + if( f->size < 1 ) + { + f->wait_empty = 1; + hb_cond_timedwait( f->cond_empty, f->lock, FIFO_TIMEOUT ); + if( f->size < 1 ) + { + hb_unlock( f->lock ); + return NULL; + } + } + b = f->first; hb_unlock( f->lock ); return b; @@ -309,6 +396,57 @@ hb_buffer_t * hb_fifo_see2( hb_fifo_t * f ) return b; } +int hb_fifo_full_wait( hb_fifo_t * f ) +{ + int result; + + hb_lock( f->lock ); + if( f->size >= f->capacity ) + { + f->wait_full = 1; + hb_cond_timedwait( f->cond_full, f->lock, FIFO_TIMEOUT ); + } + result = ( f->size < f->capacity ); + hb_unlock( f->lock ); + return result; +} + +void hb_fifo_push_wait( hb_fifo_t * f, hb_buffer_t * b ) +{ + if( !b ) + { + return; + } + + hb_lock( f->lock ); + if( f->size >= f->capacity ) + { + f->wait_full = 1; + hb_cond_timedwait( f->cond_full, f->lock, FIFO_TIMEOUT ); + } + if( f->size > 0 ) + { + f->last->next = b; + } + else + { + f->first = b; + } + f->last = b; + f->size += 1; + while( f->last->next ) + { + f->size += 1; + f->last = f->last->next; + } + if( f->wait_empty && f->size >= f->thresh ) + { + f->wait_empty = 0; + hb_cond_signal( f->cond_empty ); + } + hb_unlock( f->lock ); +} + void hb_fifo_push( hb_fifo_t * f, hb_buffer_t * b ) { if( !b ) @@ -332,6 +470,11 @@ void hb_fifo_push( hb_fifo_t * f, hb_buffer_t * b ) f->size += 1; f->last = f->last->next; } + if( f->wait_empty && f->size >= f->thresh ) + { + f->wait_empty = 0; + hb_cond_signal( f->cond_empty ); + } hb_unlock( f->lock ); } @@ -384,7 +527,25 @@ void hb_fifo_close( hb_fifo_t ** _f ) } hb_lock_close( &f->lock ); + hb_cond_close( &f->cond_empty ); + hb_cond_close( &f->cond_full ); free( f ); *_f = NULL; } + +void hb_fifo_flush( hb_fifo_t * f ) +{ + hb_buffer_t * b; + + while( ( b = hb_fifo_get( f ) ) ) + { + hb_buffer_close( &b ); + } + hb_lock( f->lock ); + hb_cond_signal( f->cond_empty ); + hb_cond_signal( f->cond_full ); + hb_unlock( f->lock ); + +} +