summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/fifo.c166
1 files changed, 166 insertions, 0 deletions
diff --git a/libhb/fifo.c b/libhb/fifo.c
index cb2b4b6ce..9c76b01ba 100644
--- a/libhb/fifo.c
+++ b/libhb/fifo.c
@@ -11,6 +11,7 @@
#endif
#define FIFO_TIMEOUT 200
+//#define HB_FIFO_DEBUG 1
/* Fifo */
struct hb_fifo_s
@@ -26,7 +27,19 @@ struct hb_fifo_s
uint32_t buffer_size;
hb_buffer_t * first;
hb_buffer_t * last;
+
+#if defined(HB_FIFO_DEBUG)
+ // Fifo list for debugging
+ hb_fifo_t * next;
+#endif
+};
+
+#if defined(HB_FIFO_DEBUG)
+static hb_fifo_t fifo_list =
+{
+ .next = NULL
};
+#endif
/* we round the requested buffer size up to the next power of 2 so there can
* be at most 32 possible pools when the size is a 32 bit int. To avoid a lot
@@ -68,6 +81,147 @@ void hb_buffer_pool_init( void )
}
}
+#if defined(HB_FIFO_DEBUG)
+
+static void dump_fifo(hb_fifo_t * f)
+{
+ hb_buffer_t * b = f->first;
+
+ if (b)
+ {
+ while (b)
+ {
+ fprintf(stderr, "%p:%d:%d\n", b, b->size, b->alloc);
+ b = b->next;
+ }
+ fprintf(stderr, "\n");
+ }
+}
+
+static void fifo_list_add( hb_fifo_t * f )
+{
+ hb_fifo_t *next = fifo_list.next;
+
+ fifo_list.next = f;
+ f->next = next;
+}
+
+static void fifo_list_rem( hb_fifo_t * f )
+{
+ hb_fifo_t *next, *prev;
+
+ prev = &fifo_list;
+ next = fifo_list.next;
+
+ while ( next && next != f )
+ {
+ prev = next;
+ next = next->next;
+ }
+ if ( next == f )
+ {
+ prev->next = f->next;
+ }
+}
+
+// These routines are useful for finding and debugging problems
+// with the fifos and buffer pools
+static void buffer_pool_validate( hb_fifo_t * f )
+{
+ hb_buffer_t *b;
+
+ hb_lock( f->lock );
+ b = f->first;
+ while (b)
+ {
+ if (b->alloc != f->buffer_size)
+ {
+ fprintf(stderr, "Invalid buffer pool size! buf %p size %d pool size %d\n", b, b->alloc, f->buffer_size);
+ dump_fifo( f );
+ *(char*)0 = 1;
+ }
+ b = b->next;
+ }
+
+ hb_unlock( f->lock );
+}
+
+static void buffer_pools_validate( void )
+{
+ int ii;
+ for ( ii = 10; ii < 26; ++ii )
+ {
+ buffer_pool_validate( buffers.pool[ii] );
+ }
+}
+
+void fifo_list_validate( void )
+{
+ hb_fifo_t *next = fifo_list.next;
+ hb_fifo_t *m;
+ hb_buffer_t *b, *c;
+ int count;
+
+ buffer_pools_validate();
+ while ( next )
+ {
+ count = 0;
+ hb_lock( next->lock );
+ b = next->first;
+
+ // Count the number of entries in this fifo
+ while (b)
+ {
+ c = b->next;
+ // check that the current buffer is not duplicated in this fifo
+ while (c)
+ {
+ if (c == b)
+ {
+ fprintf(stderr, "Duplicate buffer in fifo!\n");
+ dump_fifo(next);
+ *(char*)0 = 1;
+ }
+ c = c->next;
+ }
+
+ // check that the current buffer is not duplicated in another fifo
+ m = next->next;
+ while (m)
+ {
+ hb_lock( m->lock );
+ c = m->first;
+ while (c)
+ {
+ if (c == b)
+ {
+ fprintf(stderr, "Duplicate buffer in another fifo!\n");
+ dump_fifo(next);
+ *(char*)0 = 1;
+ }
+ c = c->next;
+ }
+ hb_unlock( m->lock );
+ m = m->next;
+ }
+
+ count++;
+ b = b->next;
+ }
+
+ if ( count != next->size )
+ {
+ fprintf(stderr, "Invalid fifo size! count %d size %d\n", count, next->size);
+ dump_fifo(next);
+ *(char*)0 = 1;
+ }
+ hb_unlock( next->lock );
+
+ next = next->next;
+ }
+}
+#endif
+
void hb_buffer_pool_free( void )
{
int i;
@@ -204,6 +358,7 @@ void hb_buffer_reduce( hb_buffer_t * b, int size )
hb_buffer_swap_copy( b, tmp );
memcpy( b->data, tmp->data, size );
+ tmp->next = NULL;
hb_buffer_close( &tmp );
}
}
@@ -260,6 +415,11 @@ hb_fifo_t * hb_fifo_init( int capacity, int thresh )
f->capacity = capacity;
f->thresh = thresh;
f->buffer_size = 0;
+
+#if defined(HB_FIFO_DEBUG)
+ // Add the fifo to the global fifo list
+ fifo_list_add( f );
+#endif
return f;
}
@@ -586,6 +746,12 @@ 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 );
+
+#if defined(HB_FIFO_DEBUG)
+ // Remove the fifo from the global fifo list
+ fifo_list_rem( f );
+#endif
+
free( f );
*_f = NULL;