2 * mlt_pool.c -- memory pooling functionality
3 * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
4 * Author: Charles Yates <charles.yates@pandora.be>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "mlt_properties.h"
22 #include "mlt_deque.h"
28 /** Singleton repositories
31 static mlt_properties pools
= NULL
;
33 /** Private pooling structure.
36 typedef struct mlt_pool_s
44 /** Private release structure
47 typedef struct mlt_release_s
57 static mlt_pool
pool_init( int size
)
60 mlt_pool
this = calloc( 1, sizeof( struct mlt_pool_s
) );
65 // Initialise the mutex
66 pthread_mutex_init( &this->lock
, NULL
);
69 this->stack
= mlt_deque_init( );
79 /** Get an item from the pool.
82 static mlt_release
pool_fetch( mlt_pool
this )
84 // We will generate a release object
85 mlt_release release
= NULL
;
91 pthread_mutex_lock( &this->lock
);
93 // Check if the stack is empty
94 if ( mlt_deque_count( this->stack
) != 0 )
96 // Pop the top of the stack
97 release
= mlt_deque_pop_back( this->stack
);
101 // We need to generate a release item
102 release
= calloc( 1, sizeof( struct mlt_release_s
) );
105 if ( release
!= NULL
)
107 // Allocate the real memory
108 release
->ptr
= malloc( this->size
);
111 release
->pool
= this;
116 pthread_mutex_unlock( &this->lock
);
119 // Return the generated release object
123 /** Return an item to the pool.
126 static void pool_return( mlt_pool
this, mlt_release that
)
129 if ( this != NULL
&& that
!= NULL
)
131 // Ensure that the pools match
132 if ( this == that
->pool
)
135 pthread_mutex_lock( &this->lock
);
137 // Push the that back back on to the stack
138 mlt_deque_push_back( this->stack
, that
);
141 pthread_mutex_unlock( &this->lock
);
143 // Ensure that we don't clean up
148 // Tidy up - this will only occur if the returned item is incorrect
154 // Free the release itself
162 static void pool_close( mlt_pool
this )
166 // We need to free up all items in the pool
167 mlt_release release
= NULL
;
169 // Iterate through the stack until depleted
170 while ( ( release
= mlt_deque_pop_back( this->stack
) ) != NULL
)
172 // We'll return this item to NULL
173 pool_return( NULL
, release
);
176 // We can now close the stack
177 mlt_deque_close( this->stack
);
180 pthread_mutex_destroy( &this->lock
);
187 /** Initialise the pool.
190 void mlt_pool_init( )
192 // Loop variable used to create the pools
196 pools
= mlt_properties_new( );
199 for ( i
= 8; i
< 32; i
++ )
201 // Each properties item needs a name
205 mlt_pool pool
= pool_init( 1 << i
);
208 sprintf( name
, "%d", i
);
210 // Register with properties
211 mlt_properties_set_data( pools
, name
, pool
, 0, ( mlt_destructor
)pool_close
, NULL
);
215 /** Allocate size bytes from the pool.
218 void *mlt_pool_allocate( int size
, void **release
)
220 // This is the real release structure we'll return
221 mlt_release real
= NULL
;
223 // This will be used to obtain the pool to use
224 mlt_pool pool
= NULL
;
226 // Determines the index of the pool to use
229 // Minimum size pooled is 256 bytes
231 while ( ( 1 << index
) < size
)
234 // Now get the pool at the index
235 pool
= mlt_properties_get_data_at( pools
, index
+ 1, NULL
);
237 // Now get the real item
238 real
= pool_fetch( pool
);
246 // Return the pointer
250 // Otherwise return a NULL to indicate failure
254 /** Release the allocated memory.
257 void mlt_pool_release( void *release
)
260 if ( release
!= NULL
)
262 // Get the real release structure
263 mlt_release real
= release
;
265 // Return to the pool
266 pool_return( real
->pool
, real
);
273 void mlt_pool_close( )
275 // Close the properties
276 mlt_properties_close( pools
);