]> git.sesse.net Git - mlt/blobdiff - src/framework/mlt_pool.c
Rename this to self in the framework.
[mlt] / src / framework / mlt_pool.c
index ee1d2441f9b65dcd925338064df9696aa0dc4b28..980e03970f8247d402a974ae31b97003149b9fbd 100644 (file)
@@ -1,21 +1,24 @@
-/*
- * mlt_pool.c -- memory pooling functionality
- * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
- * Author: Charles Yates <charles.yates@pandora.be>
+/**
+ * \file mlt_pool.c
+ * \brief memory pooling functionality
+ * \see mlt_pool_s
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2003-2009 Ushodaya Enterprises Limited
+ * \author Charles Yates <charles.yates@pandora.be>
  *
- * This program is distributed in the hope that it will be useful,
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "mlt_properties.h"
 #include <malloc.h>
 #endif
 
-/** Singleton repositories
-*/
+/** global singleton for tracking pools */
 
 static mlt_properties pools = NULL;
 
-/** Private pooling structure.
-*/
+/** \brief Pool (memory) class
+ */
 
 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;
 
-typedef struct mlt_release_s
+/** \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 __attribute__ ((aligned (16))) mlt_release_s
 {
        mlt_pool pool;
        int references;
@@ -55,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;
@@ -106,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
@@ -137,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 )
 {
@@ -145,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;
@@ -170,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( )
 {
@@ -231,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 )
 {
@@ -242,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 ++;
 
@@ -254,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 )
 {
@@ -265,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 ) )
@@ -295,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( )
 {
@@ -305,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 )
 {
@@ -332,20 +369,22 @@ void mlt_pool_release( void *release )
 }
 
 /** Close the pool.
-*/
+ *
+ * \public \memberof mlt_pool_s
+ */
 
 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 ) ? '*' : ' ' );
+                       mlt_log( NULL, MLT_LOG_DEBUG, "%s: size %d allocated %d returned %d %c\n", __FUNCTION__,
+                               pool->size, pool->count, mlt_deque_count( pool->stack ),
+                               pool->count !=  mlt_deque_count( pool->stack ) ? '*' : ' ' );
        }
 #endif