X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fframework%2Fmlt_pool.c;h=ee1d2441f9b65dcd925338064df9696aa0dc4b28;hb=d61a4ab32e7b834996d394b2e8032680e05109ff;hp=16d1e1d4fd3ca0608ffa888c27c94e408f9d8bb9;hpb=0b288164cbeb9a3c98107d439d86844be13ba910;p=melted diff --git a/src/framework/mlt_pool.c b/src/framework/mlt_pool.c index 16d1e1d..ee1d244 100644 --- a/src/framework/mlt_pool.c +++ b/src/framework/mlt_pool.c @@ -25,6 +25,11 @@ #include #include +// Not nice - memalign is defined here apparently? +#ifdef linux +#include +#endif + /** Singleton repositories */ @@ -45,6 +50,7 @@ typedef struct mlt_pool_s typedef struct mlt_release_s { mlt_pool pool; + int references; } *mlt_release; @@ -92,18 +98,31 @@ static void *pool_fetch( mlt_pool this ) { // Pop the top of the stack ptr = mlt_deque_pop_back( this->stack ); + + // Assign the reference + ( ( mlt_release )ptr )->references = 1; } else { // We need to generate a release item - mlt_release release = malloc( sizeof( struct mlt_release_s ) + this->size ); +#ifdef linux + mlt_release release = memalign( 16, this->size ); +#else + mlt_release release = malloc( this->size ); +#endif // Initialise it if ( release != NULL ) { + // Increment the number of items allocated to this pool + this->count ++; + // Assign the pool release->pool = this; + // Assign the reference + release->references = 1; + // Determine the ptr ptr = ( void * )release + sizeof( struct mlt_release_s ); } @@ -126,7 +145,7 @@ static void pool_return( void *ptr ) if ( ptr != NULL ) { // Get the release pointer - mlt_release that = ( void * )ptr - sizeof( struct mlt_release_s ); + mlt_release that = ptr - sizeof( struct mlt_release_s ); // Get the pool mlt_pool this = that->pool; @@ -220,15 +239,15 @@ void *mlt_pool_alloc( int size ) mlt_pool pool = NULL; // Determines the index of the pool to use - int index = 0; + int index = 8; // Minimum size pooled is 256 bytes - size = size >> 8; + size = size + sizeof( mlt_release ); while ( ( 1 << index ) < size ) index ++; // Now get the pool at the index - pool = mlt_properties_get_data_at( pools, index + 1, NULL ); + pool = mlt_properties_get_data_at( pools, index - 8, NULL ); // Now get the real item return pool_fetch( pool ); @@ -237,33 +256,70 @@ void *mlt_pool_alloc( int size ) /** Allocate size bytes from the pool. */ -void *mlt_pool_allocate( int size, void **release ) +void *mlt_pool_realloc( void *ptr, int size ) { - // This is the real release structure we'll return - void *real = NULL; + // Result to return + void *result = NULL; - // This will be used to obtain the pool to use - mlt_pool pool = NULL; + // Check if we actually have an address + if ( ptr != NULL ) + { + // Get the release pointer + mlt_release that = ptr - sizeof( struct mlt_release_s ); - // Determines the index of the pool to use - int index = 0; + // If the current pool this ptr belongs to is big enough + if ( size > that->pool->size - sizeof( struct mlt_release_s ) ) + { + // Allocate + result = mlt_pool_alloc( size ); - // Minimum size pooled is 256 bytes - size = size >> 8; - while ( ( 1 << index ) < size ) - index ++; + // Copy + memcpy( result, ptr, that->pool->size - sizeof( struct mlt_release_s ) ); - // Now get the pool at the index - pool = mlt_properties_get_data_at( pools, index + 1, NULL ); + // Release + mlt_pool_release( ptr ); + } + else + { + // Nothing to do + result = ptr; + } + } + else + { + // Simply allocate + result = mlt_pool_alloc( size ); + } - // Now get the real item - real = pool_fetch( pool ); + return result; +} - // Assign to release - *release = real; - - // Otherwise return a NULL to indicate failure - return real; +/** Purge unused items in the pool. +*/ + +void mlt_pool_purge( ) +{ + int i = 0; + + // For each pool + for ( i = 0; i < mlt_properties_count( pools ); i ++ ) + { + // Get the pool + mlt_pool this = mlt_properties_get_data_at( pools, i, NULL ); + + // Pointer to unused memory + void *release = NULL; + + // Lock the pool + pthread_mutex_lock( &this->lock ); + + // We'll free all unused items now + while ( ( release = mlt_deque_pop_back( this->stack ) ) != NULL ) + free( release - sizeof( struct mlt_release_s ) ); + + // Unlock the pool + pthread_mutex_unlock( &this->lock ); + } } /** Release the allocated memory. @@ -280,6 +336,19 @@ void mlt_pool_release( void *release ) void mlt_pool_close( ) { +#ifdef _MLT_POOL_CHECKS_ + // Stats dump on close + int i = 0; + fprintf( stderr, "Usage:\n\n" ); + for ( i = 0; i < mlt_properties_count( pools ); i ++ ) + { + mlt_pool pool = mlt_properties_get_data_at( pools, i, NULL ); + if ( pool->count ) + fprintf( stderr, "%d: allocated %d returned %d %c\n", pool->size, pool->count, mlt_deque_count( pool->stack ), + pool->count != mlt_deque_count( pool->stack ) ? '*' : ' ' ); + } +#endif + // Close the properties mlt_properties_close( pools ); }