/* $Id: fifo.c,v 1.17 2005/10/15 18:05:03 titer Exp $
This file is part of the HandBrake source code.
Homepage: .
It may be used under the terms of the GNU General Public License. */
#include "hb.h"
#ifndef SYS_DARWIN
#include
#endif
hb_buffer_t * hb_buffer_init( int size )
{
hb_buffer_t * b;
if( !( b = calloc( sizeof( hb_buffer_t ), 1 ) ) )
{
hb_log( "out of memory" );
return NULL;
}
b->alloc = size;
b->size = size;
#if defined( SYS_DARWIN ) || defined( SYS_FREEBSD )
b->data = malloc( size );
#elif defined( SYS_CYGWIN )
/* FIXME */
b->data = malloc( size + 17 );
#else
b->data = memalign( 16, size );
#endif
if( !b->data )
{
hb_log( "out of memory" );
free( b );
return NULL;
}
return b;
}
void hb_buffer_realloc( hb_buffer_t * b, int size )
{
/* No more alignment, but we don't care */
b->data = realloc( b->data, size );
b->alloc = size;
}
void hb_buffer_close( hb_buffer_t ** _b )
{
hb_buffer_t * b = *_b;
if( b->data )
{
free( b->data );
}
free( b );
*_b = NULL;
}
/* Fifo */
struct hb_fifo_s
{
hb_lock_t * lock;
int capacity;
int size;
hb_buffer_t * first;
hb_buffer_t * last;
};
hb_fifo_t * hb_fifo_init( int capacity )
{
hb_fifo_t * f;
f = calloc( sizeof( hb_fifo_t ), 1 );
f->lock = hb_lock_init();
f->capacity = capacity;
return f;
}
int hb_fifo_size( hb_fifo_t * f )
{
int ret;
hb_lock( f->lock );
ret = f->size;
hb_unlock( f->lock );
return ret;
}
int hb_fifo_is_full( hb_fifo_t * f )
{
int ret;
hb_lock( f->lock );
ret = ( f->size >= f->capacity );
hb_unlock( f->lock );
return ret;
}
float hb_fifo_percent_full( hb_fifo_t * f )
{
float ret;
hb_lock( f->lock );
ret = f->size / f->capacity;
hb_unlock( f->lock );
return ret;
}
hb_buffer_t * hb_fifo_get( hb_fifo_t * f )
{
hb_buffer_t * b;
hb_lock( f->lock );
if( f->size < 1 )
{
hb_unlock( f->lock );
return NULL;
}
b = f->first;
f->first = b->next;
b->next = NULL;
f->size -= 1;
hb_unlock( f->lock );
return b;
}
hb_buffer_t * hb_fifo_see( hb_fifo_t * f )
{
hb_buffer_t * b;
hb_lock( f->lock );
if( f->size < 1 )
{
hb_unlock( f->lock );
return NULL;
}
b = f->first;
hb_unlock( f->lock );
return b;
}
hb_buffer_t * hb_fifo_see2( hb_fifo_t * f )
{
hb_buffer_t * b;
hb_lock( f->lock );
if( f->size < 2 )
{
hb_unlock( f->lock );
return NULL;
}
b = f->first->next;
hb_unlock( f->lock );
return b;
}
void hb_fifo_push( hb_fifo_t * f, hb_buffer_t * b )
{
if( !b )
{
return;
}
hb_lock( f->lock );
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;
}
hb_unlock( f->lock );
}
void hb_fifo_close( hb_fifo_t ** _f )
{
hb_fifo_t * f = *_f;
hb_buffer_t * b;
hb_log( "fifo_close: trashing %d buffer(s)", hb_fifo_size( f ) );
while( ( b = hb_fifo_get( f ) ) )
{
hb_buffer_close( &b );
}
hb_lock_close( &f->lock );
free( f );
*_f = NULL;
}