X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fframework%2Fmlt_pool.c;h=980e03970f8247d402a974ae31b97003149b9fbd;hb=12a7f692213dbafae42e02744fd734ca90d1cdde;hp=e4d47dd40392ee31d28d8f20d1b9c7ec278be4ce;hpb=51f99c29759e71318c4c575f8a68cf1b5d1c5137;p=mlt diff --git a/src/framework/mlt_pool.c b/src/framework/mlt_pool.c index e4d47dd4..980e0397 100644 --- a/src/framework/mlt_pool.c +++ b/src/framework/mlt_pool.c @@ -1,8 +1,9 @@ /** * \file mlt_pool.c * \brief memory pooling functionality + * \see mlt_pool_s * - * Copyright (C) 2003-2008 Ushodaya Enterprises Limited + * Copyright (C) 2003-2009 Ushodaya Enterprises Limited * \author Charles Yates * * This library is free software; you can redistribute it and/or @@ -32,8 +33,7 @@ #include #endif -/** Singleton repositories -*/ +/** global singleton for tracking pools */ static mlt_properties pools = NULL; @@ -42,17 +42,20 @@ static mlt_properties pools = NULL; typedef struct mlt_pool_s { - pthread_mutex_t lock; - mlt_deque stack; - int size; - int count; + pthread_mutex_t lock; ///< lock to prevent race conditions + mlt_deque stack; ///< a stack of addresses to memory blocks + int size; ///< the size of the memory block as a power of 2 + int count; ///< the number of blocks in the pool } *mlt_pool; /** \brief private to mlt_pool_s, for tracking items to release + * + * Aligned to 16 byte in case we toss buffers to external assembly + * optimized libraries (sse/altivec). */ -typedef struct mlt_release_s +typedef struct __attribute__ ((aligned (16))) mlt_release_s { mlt_pool pool; int references; @@ -60,49 +63,57 @@ typedef struct mlt_release_s *mlt_release; /** Create a pool. -*/ + * + * \private \memberof mlt_pool_s + * \param size the size of the memory blocks to hold as some power of two + * \return a new pool object + */ static mlt_pool pool_init( int size ) { // Create the pool - mlt_pool this = calloc( 1, sizeof( struct mlt_pool_s ) ); + mlt_pool self = calloc( 1, sizeof( struct mlt_pool_s ) ); // Initialise it - if ( this != NULL ) + if ( self != NULL ) { // Initialise the mutex - pthread_mutex_init( &this->lock, NULL ); + pthread_mutex_init( &self->lock, NULL ); // Create the stack - this->stack = mlt_deque_init( ); + self->stack = mlt_deque_init( ); // Assign the size - this->size = size; + self->size = size; } // Return it - return this; + return self; } /** Get an item from the pool. -*/ + * + * \private \memberof mlt_pool_s + * \param self a pool + * \return an opaque pointer + */ -static void *pool_fetch( mlt_pool this ) +static void *pool_fetch( mlt_pool self ) { // We will generate a release object void *ptr = NULL; // Sanity check - if ( this != NULL ) + if ( self != NULL ) { // Lock the pool - pthread_mutex_lock( &this->lock ); + pthread_mutex_lock( &self->lock ); // Check if the stack is empty - if ( mlt_deque_count( this->stack ) != 0 ) + if ( mlt_deque_count( self->stack ) != 0 ) { // Pop the top of the stack - ptr = mlt_deque_pop_back( this->stack ); + ptr = mlt_deque_pop_back( self->stack ); // Assign the reference ( ( mlt_release )ptr )->references = 1; @@ -111,30 +122,30 @@ static void *pool_fetch( mlt_pool this ) { // We need to generate a release item #ifdef linux - mlt_release release = memalign( 16, this->size ); + mlt_release release = memalign( 16, self->size ); #else - mlt_release release = malloc( this->size ); + mlt_release release = malloc( self->size ); #endif // Initialise it if ( release != NULL ) { // Increment the number of items allocated to this pool - this->count ++; + self->count ++; // Assign the pool - release->pool = this; + release->pool = self; // Assign the reference release->references = 1; // Determine the ptr - ptr = ( void * )release + sizeof( struct mlt_release_s ); + ptr = ( char * )release + sizeof( struct mlt_release_s ); } } // Unlock the pool - pthread_mutex_unlock( &this->lock ); + pthread_mutex_unlock( &self->lock ); } // Return the generated release object @@ -142,7 +153,10 @@ static void *pool_fetch( mlt_pool this ) } /** Return an item to the pool. -*/ + * + * \private \memberof mlt_pool_s + * \param ptr an opaque pointer + */ static void pool_return( void *ptr ) { @@ -150,21 +164,21 @@ static void pool_return( void *ptr ) if ( ptr != NULL ) { // Get the release pointer - mlt_release that = ptr - sizeof( struct mlt_release_s ); + mlt_release that = ( void * )(( char * )ptr - sizeof( struct mlt_release_s )); // Get the pool - mlt_pool this = that->pool; + mlt_pool self = that->pool; - if ( this != NULL ) + if ( self != NULL ) { // Lock the pool - pthread_mutex_lock( &this->lock ); + pthread_mutex_lock( &self->lock ); // Push the that back back on to the stack - mlt_deque_push_back( this->stack, ptr ); + mlt_deque_push_back( self->stack, ptr ); // Unlock the pool - pthread_mutex_unlock( &this->lock ); + pthread_mutex_unlock( &self->lock ); // Ensure that we don't clean up ptr = NULL; @@ -175,40 +189,45 @@ static void pool_return( void *ptr ) if ( ptr != NULL ) { // Free the release itself - free( ptr - sizeof( struct mlt_release_s ) ); + free( ( char * )ptr - sizeof( struct mlt_release_s ) ); } } /** Destroy a pool. -*/ + * + * \private \memberof mlt_pool_s + * \param self a pool + */ -static void pool_close( mlt_pool this ) +static void pool_close( mlt_pool self ) { - if ( this != NULL ) + if ( self != NULL ) { // We need to free up all items in the pool void *release = NULL; // Iterate through the stack until depleted - while ( ( release = mlt_deque_pop_back( this->stack ) ) != NULL ) + while ( ( release = mlt_deque_pop_back( self->stack ) ) != NULL ) { // We'll free this item now - free( release - sizeof( struct mlt_release_s ) ); + free( ( char * )release - sizeof( struct mlt_release_s ) ); } // We can now close the stack - mlt_deque_close( this->stack ); + mlt_deque_close( self->stack ); // Destroy the mutex - pthread_mutex_destroy( &this->lock ); + pthread_mutex_destroy( &self->lock ); // Close the pool - free( this ); + free( self ); } } -/** Initialise the pool. -*/ +/** Initialise the global pool. + * + * \public \memberof mlt_pool_s + */ void mlt_pool_init( ) { @@ -236,7 +255,10 @@ void mlt_pool_init( ) } /** Allocate size bytes from the pool. -*/ + * + * \public \memberof mlt_pool_s + * \param size the number of bytes + */ void *mlt_pool_alloc( int size ) { @@ -247,7 +269,7 @@ void *mlt_pool_alloc( int size ) int index = 8; // Minimum size pooled is 256 bytes - size = size + sizeof( mlt_release ); + size += sizeof( struct mlt_release_s ); while ( ( 1 << index ) < size ) index ++; @@ -259,7 +281,11 @@ void *mlt_pool_alloc( int size ) } /** Allocate size bytes from the pool. -*/ + * + * \public \memberof mlt_pool_s + * \param ptr an opaque pointer - can be in the pool or a new block to allocate + * \param size the number of bytes + */ void *mlt_pool_realloc( void *ptr, int size ) { @@ -270,7 +296,7 @@ void *mlt_pool_realloc( void *ptr, int size ) if ( ptr != NULL ) { // Get the release pointer - mlt_release that = ptr - sizeof( struct mlt_release_s ); + mlt_release that = ( void * )(( char * )ptr - sizeof( struct mlt_release_s )); // If the current pool this ptr belongs to is big enough if ( size > that->pool->size - sizeof( struct mlt_release_s ) ) @@ -300,7 +326,10 @@ void *mlt_pool_realloc( void *ptr, int size ) } /** Purge unused items in the pool. -*/ + * + * A form of garbage collection. + * \public \memberof mlt_pool_s + */ void mlt_pool_purge( ) { @@ -310,25 +339,28 @@ void mlt_pool_purge( ) for ( i = 0; i < mlt_properties_count( pools ); i ++ ) { // Get the pool - mlt_pool this = mlt_properties_get_data_at( pools, i, NULL ); + mlt_pool self = mlt_properties_get_data_at( pools, i, NULL ); // Pointer to unused memory void *release = NULL; // Lock the pool - pthread_mutex_lock( &this->lock ); + pthread_mutex_lock( &self->lock ); // We'll free all unused items now - while ( ( release = mlt_deque_pop_back( this->stack ) ) != NULL ) - free( release - sizeof( struct mlt_release_s ) ); + while ( ( release = mlt_deque_pop_back( self->stack ) ) != NULL ) + free( ( char * )release - sizeof( struct mlt_release_s ) ); // Unlock the pool - pthread_mutex_unlock( &this->lock ); + pthread_mutex_unlock( &self->lock ); } } /** Release the allocated memory. -*/ + * + * \public \memberof mlt_pool_s + * \param release an opaque pointer of a block in the pool + */ void mlt_pool_release( void *release ) { @@ -337,7 +369,9 @@ void mlt_pool_release( void *release ) } /** Close the pool. -*/ + * + * \public \memberof mlt_pool_s + */ void mlt_pool_close( ) {