#include <iostream>
#include <vector>
#include <stdio.h>
#include <sys/time.h>
using namespace std;
#define MPOOL_DEFAULT_ITEMS 6000
// #define DEBUG 1
#ifdef DEBUG
# define DBG printf
#else
# define DBG //
#endif
#define ADDRESS_OF(o) reinterpret_cast<unsigned long>(o)
template< typename object_t >
class MemPool {
private :
struct pool_item {
unsigned free : 1;
object_t *object;
pool_item (){
free = 1;
object = new object_t;
}
};
vector<pool_item *> m_pool;
public :
MemPool( unsigned int items = MPOOL_DEFAULT_ITEMS );
~MemPool();
object_t *alloc();
void free( object_t *o );
void free( int index );
inline unsigned long size(){
return m_pool.size() * (sizeof(pool_item) + sizeof(object_t));
}
};
template< typename object_t > MemPool<object_t>::MemPool( unsigned int items /*= MPOOL_DEFAULT_ITEMS*/ ){
unsigned int i;
DBG( "* Pre alloco %d oggetti ... \n", items );
for( i = 0; i < items; i++ ){
m_pool.push_back( new pool_item );
}
DBG( "* fatto .\n" );
}
template< typename object_t > MemPool<object_t>::~MemPool(){
unsigned int i;
pool_item *item = NULL;
DBG( "* De alloco tutto ... \n" );
for( i = 0; i < m_pool.size(); i++ ){
item = m_pool[i];
delete item->object;
delete item;
}
m_pool.clear();
DBG( "* fatto .\n" );
}
template< typename object_t > object_t * MemPool<object_t>::alloc(){
unsigned int i, size = m_pool.size();
pool_item *item = NULL;
DBG( "* Cerco un elemento libero ... " );
/* find first free item */
for( i = 0; i < size; i++ ){
item = m_pool[i];
if( item->free == 1 ){
DBG( "trovato a %p .\n", item->object );
item->free = 0;
return item->object;
}
}
/* no free item found, expand pool */
DBG( "non trovato, espando il pool .\n" );
item = new pool_item;
m_pool.push_back(item);
return item->object;
}
template< typename object_t > void MemPool<object_t>::free( object_t *o ){
unsigned long o_address = ADDRESS_OF(o);
unsigned int i, size = m_pool.size();
pool_item *item = NULL;
DBG( "* Libero %p ... ", o );
/* check object ownership */
for( i = 0; i < size; i++ ){
item = m_pool[i];
if( ADDRESS_OF(item->object) == o_address ){
DBG( "trovato, libero .\n" );
if( m_pool.size() > MPOOL_DEFAULT_ITEMS ){
delete item->object;
delete item;
m_pool.erase( m_pool.begin() + i );
}
else{
item->free = 1;
}
return;
}
}
DBG( "non trovato, chiamo l'operatore delete .\n" );
delete o;
}
template< typename object_t > void MemPool<object_t>::free( int index ){
pool_item *item = NULL;
DBG( "* Libero %d ... \n", index );
item = m_pool[index];
if( m_pool.size() > MPOOL_DEFAULT_ITEMS ){
m_pool.erase( m_pool.begin() + index );
delete item->object;
delete item;
}
else{
item->free = 1;
}
}
class Object {
public:
Object(){
DBG( "\t* Oggetto creato .\n" );
}
~Object(){
DBG( "\t* Oggetto distrutto .\n" );
}
};
long ticks(){
timeval ts;
gettimeofday(&ts,0);
return ts.tv_sec * 1000 + (ts.tv_usec / 1000);
}
int main()
{
MemPool<Object> pool(10);
Object *o;
vector<Object *> tmp;
long start, end;
int i;
start = ticks();
for( i = 0; i < 4000; i++ ){
tmp.push_back( pool.alloc() );
}
end = ticks();
printf( "Pool : %d ms, %d bytes\n", end - start, pool.size() );
start = ticks();
for( i = 0; i < 4000; i++ ){
o = new Object;
}
end = ticks();
printf( "New : %d ms, %d bytes\n", end - start, 400 * sizeof(Object) );
return 0;
}