Memory pooling part 2 and other optimisations
[melted] / src / framework / mlt_pool.c
index ab51392..16d1e1d 100644 (file)
@@ -38,15 +38,12 @@ typedef struct mlt_pool_s
        pthread_mutex_t lock;
        mlt_deque stack;
        int size;
+       int count;
 }
 *mlt_pool;
 
-/** Private release structure
-*/
-
 typedef struct mlt_release_s
 {
-       void *ptr;
        mlt_pool pool;
 }
 *mlt_release;
@@ -79,10 +76,10 @@ static mlt_pool pool_init( int size )
 /** Get an item from the pool.
 */
 
-static mlt_release pool_fetch( mlt_pool this )
+static void *pool_fetch( mlt_pool this )
 {
        // We will generate a release object
-       mlt_release release = NULL;
+       void *ptr = NULL;
 
        // Sanity check
        if ( this != NULL )
@@ -94,21 +91,21 @@ static mlt_release pool_fetch( mlt_pool this )
                if ( mlt_deque_count( this->stack ) != 0 )
                {
                        // Pop the top of the stack
-                       release = mlt_deque_pop_back( this->stack );
+                       ptr = mlt_deque_pop_back( this->stack );
                }
                else
                {
                        // We need to generate a release item
-                       release = calloc( 1, sizeof( struct mlt_release_s ) );
+                       mlt_release release = malloc( sizeof( struct mlt_release_s ) + this->size );
 
                        // Initialise it
                        if ( release != NULL )
                        {
-                               // Allocate the real memory
-                               release->ptr = malloc( this->size );
-
                                // Assign the pool
                                release->pool = this;
+
+                               // Determine the ptr
+                               ptr = ( void * )release + sizeof( struct mlt_release_s );
                        }
                }
 
@@ -117,42 +114,44 @@ static mlt_release pool_fetch( mlt_pool this )
        }
 
        // Return the generated release object
-       return release;
+       return ptr;
 }
 
 /** Return an item to the pool.
 */
 
-static void pool_return( mlt_pool this, mlt_release that )
+static void pool_return( void *ptr )
 {
        // Sanity checks
-       if ( this != NULL && that != NULL )
+       if ( ptr != NULL )
        {
-               // Ensure that the pools match
-               if ( this == that->pool )
+               // Get the release pointer
+               mlt_release that = ( void * )ptr - sizeof( struct mlt_release_s );
+
+               // Get the pool
+               mlt_pool this = that->pool;
+
+               if ( this != NULL )
                {
                        // Lock the pool
                        pthread_mutex_lock( &this->lock );
 
                        // Push the that back back on to the stack
-                       mlt_deque_push_back( this->stack, that );
+                       mlt_deque_push_back( this->stack, ptr );
 
                        // Unlock the pool
                        pthread_mutex_unlock( &this->lock );
 
                        // Ensure that we don't clean up
-                       that = NULL;
+                       ptr = NULL;
                }
        }
 
        // Tidy up - this will only occur if the returned item is incorrect
-       if ( that != NULL )
+       if ( ptr != NULL )
        {
-               // Free the memory
-               free( that->ptr );
-
                // Free the release itself
-               free( that );
+               free( ptr - sizeof( struct mlt_release_s ) );
        }
 }
 
@@ -164,13 +163,13 @@ static void pool_close( mlt_pool this )
        if ( this != NULL )
        {
                // We need to free up all items in the pool
-               mlt_release release = NULL;
+               void *release = NULL;
 
                // Iterate through the stack until depleted
                while ( ( release = mlt_deque_pop_back( this->stack ) ) != NULL )
                {
-                       // We'll return this item to NULL
-                       pool_return( NULL, release );
+                       // We'll free this item now
+                       free( release - sizeof( struct mlt_release_s ) );
                }
 
                // We can now close the stack
@@ -196,7 +195,7 @@ void mlt_pool_init( )
        pools = mlt_properties_new( );
 
        // Create the pools
-       for ( i = 8; i < 32; i ++ )
+       for ( i = 8; i < 31; i ++ )
        {
                // Each properties item needs a name
                char name[ 32 ];
@@ -215,16 +214,39 @@ void mlt_pool_init( )
 /** Allocate size bytes from the pool.
 */
 
+void *mlt_pool_alloc( int size )
+{
+       // This will be used to obtain the pool to use
+       mlt_pool pool = NULL;
+
+       // Determines the index of the pool to use
+       int index = 0;
+
+       // Minimum size pooled is 256 bytes
+       size = size >> 8;
+       while ( ( 1 << index ) < size )
+               index ++;
+
+       // Now get the pool at the index
+       pool = mlt_properties_get_data_at( pools, index + 1, NULL );
+
+       // Now get the real item
+       return pool_fetch( pool );
+}
+
+/** Allocate size bytes from the pool.
+*/
+
 void *mlt_pool_allocate( int size, void **release )
 {
        // This is the real release structure we'll return
-       mlt_release real = NULL;
+       void *real = NULL;
 
        // This will be used to obtain the pool to use
        mlt_pool pool = NULL;
 
        // Determines the index of the pool to use
-       int index = 1;
+       int index = 0;
 
        // Minimum size pooled is 256 bytes
        size = size >> 8;
@@ -237,18 +259,11 @@ void *mlt_pool_allocate( int size, void **release )
        // Now get the real item
        real = pool_fetch( pool );
 
-       // Deal with return
-       if ( real != NULL )
-       {
-               // Assign to release
-               *release = real;
-
-               // Return the pointer
-               return real->ptr;
-       }
-
+       // Assign to release
+       *release = real;
+       
        // Otherwise return a NULL to indicate failure
-       return NULL;
+       return real;
 }
 
 /** Release the allocated memory.
@@ -256,15 +271,8 @@ void *mlt_pool_allocate( int size, void **release )
 
 void mlt_pool_release( void *release )
 {
-       // Sanity check
-       if ( release != NULL )
-       {
-               // Get the real release structure
-               mlt_release real = release;
-
-               // Return to the pool
-               pool_return( real->pool, real );
-       }
+       // Return to the pool
+       pool_return( release );
 }
 
 /** Close the pool.