daa0d297b28e0573f44327cde91529e4283cf856
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"
29 /** Singleton repositories
32 static mlt_properties pools
= NULL
;
34 /** Private pooling structure.
37 typedef struct mlt_pool_s
46 typedef struct mlt_release_s
56 static mlt_pool
pool_init( int size
)
59 mlt_pool
this = calloc( 1, sizeof( struct mlt_pool_s
) );
64 // Initialise the mutex
65 pthread_mutex_init( &this->lock
, NULL
);
68 this->stack
= mlt_deque_init( );
78 /** Get an item from the pool.
81 static void *pool_fetch( mlt_pool
this )
83 // We will generate a release object
90 pthread_mutex_lock( &this->lock
);
92 // Check if the stack is empty
93 if ( mlt_deque_count( this->stack
) != 0 )
95 // Pop the top of the stack
96 ptr
= mlt_deque_pop_back( this->stack
);
98 // Assign the reference
99 ( ( mlt_release
)ptr
)->references
= 1;
103 // We need to generate a release item
104 mlt_release release
= memalign( 16, this->size
);
107 if ( release
!= NULL
)
110 release
->pool
= this;
112 // Assign the reference
113 release
->references
= 1;
116 ptr
= ( void * )release
+ sizeof( struct mlt_release_s
);
121 pthread_mutex_unlock( &this->lock
);
124 // Return the generated release object
128 /** Return an item to the pool.
131 static void pool_return( void *ptr
)
136 // Get the release pointer
137 mlt_release that
= ptr
- sizeof( struct mlt_release_s
);
140 mlt_pool
this = that
->pool
;
145 pthread_mutex_lock( &this->lock
);
147 // Push the that back back on to the stack
148 mlt_deque_push_back( this->stack
, ptr
);
151 pthread_mutex_unlock( &this->lock
);
153 // Ensure that we don't clean up
158 // Tidy up - this will only occur if the returned item is incorrect
161 // Free the release itself
162 free( ptr
- sizeof( struct mlt_release_s
) );
169 static void pool_close( mlt_pool
this )
173 // We need to free up all items in the pool
174 void *release
= NULL
;
176 // Iterate through the stack until depleted
177 while ( ( release
= mlt_deque_pop_back( this->stack
) ) != NULL
)
179 // We'll free this item now
180 free( release
- sizeof( struct mlt_release_s
) );
183 // We can now close the stack
184 mlt_deque_close( this->stack
);
187 pthread_mutex_destroy( &this->lock
);
194 /** Initialise the pool.
197 void mlt_pool_init( )
199 // Loop variable used to create the pools
203 pools
= mlt_properties_new( );
206 for ( i
= 8; i
< 31; i
++ )
208 // Each properties item needs a name
212 mlt_pool pool
= pool_init( 1 << i
);
215 sprintf( name
, "%d", i
);
217 // Register with properties
218 mlt_properties_set_data( pools
, name
, pool
, 0, ( mlt_destructor
)pool_close
, NULL
);
222 /** Allocate size bytes from the pool.
225 void *mlt_pool_alloc( int size
)
227 // This will be used to obtain the pool to use
228 mlt_pool pool
= NULL
;
230 // Determines the index of the pool to use
233 // Minimum size pooled is 256 bytes
234 size
= size
+ sizeof( mlt_release
);
235 while ( ( 1 << index
) < size
)
238 // Now get the pool at the index
239 pool
= mlt_properties_get_data_at( pools
, index
- 8, NULL
);
241 // Now get the real item
242 return pool_fetch( pool
);
245 /** Release the allocated memory.
248 void mlt_pool_release( void *release
)
250 // Return to the pool
251 pool_return( release
);
257 void mlt_pool_close( )
259 // Close the properties
260 mlt_properties_close( pools
);