Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

/root/src/subsynth/syn/Util/FlyWeightPool.h

Go to the documentation of this file.
00001 
00002 /****************** <SYN heading BEGIN do not edit this line> *****************
00003  *
00004  * subsynth - modular audio synthesizer
00005  * subsynth is (C) Copyright 2001-2002 by Kevin Meinert
00006  *
00007  * Original Author: Kevin Meinert
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Library General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2 of the License, or (at your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Library General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Library General Public
00020  * License along with this library; if not, write to the
00021  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00022  * Boston, MA 02111-1307, USA.
00023  *
00024  * -----------------------------------------------------------------
00025  * File:          $RCSfile: FlyWeightPool.h,v $
00026  * Date modified: $Date: 2002/04/08 16:13:29 $
00027  * Version:       $Revision: 1.13 $
00028  * -----------------------------------------------------------------
00029  *
00030  ****************** <SYN heading END do not edit this line> ******************/
00031 #ifndef FLYWEIGHT_POOL
00032 #define FLYWEIGHT_POOL
00033 
00034 #include <list>
00035 #include <assert.h>
00036 #ifdef HAVE_VPR
00037 #include <vpr/Sync/Mutex.h>
00038 #endif
00039 
00040 namespace syn
00041 {
00042    
00059    template <class type>
00060    class FlyWeightPool
00061    {
00062    public:
00063       FlyWeightPool() : mAutoGrow( false ), mNumCheckedOut( 0 ), mSize( 0 ) 
00064       {
00065          this->acquire();
00066             mPool.resize( mSize );
00067          this->release();
00068       }
00069       ~FlyWeightPool()
00070       {
00071          assert( this != NULL && "this would be bad indeed" );
00072          this->acquire();
00073             assert( mNumCheckedOut == 0 && "not everyone has checked their items back into the pool" );
00074             assert( mPool.size() == mSize && "not everyone has checked their items back into the pool" );
00075             while (mPool.size() > 0)
00076             {
00077                delete mPool.front();
00078                mPool.pop_front();
00079             }
00080          this->release();
00081       }
00082       
00083       void setAutoGrow( bool grow ) { mAutoGrow = grow; }
00084       bool autoGrow() const { return mAutoGrow; }
00085 
00086 #ifdef HAVE_VPR
00087       void acquire() const { mMutex.acquire(); }
00088       bool tryAcquire() const { return mMutex.tryAcquire(); }
00089       void release() const { mMutex.release(); }
00090 #else
00091       void acquire() const {  }
00092       bool tryAcquire() const { return false; }
00093       void release() const {  }
00094 #endif 
00095 
00096       void resize( unsigned int s )
00097       {
00098          this->acquire();
00099          {
00100             this->resize_nonthreadsafe( s );
00101          }      
00102          this->release();
00103       }
00104    
00106       unsigned int size() const { return mSize; }
00107    
00109       int available() const { return mPool.size(); }
00110    
00112       bool empty() const { return mPool.size() == 0; }
00113       
00118       void take( type* &t )
00119       {
00120          this->acquire();
00121             if (mAutoGrow && this->empty())
00122             {
00123                this->resize_nonthreadsafe( (this->size() + 1) * 2 );
00124             }         
00125             assert( this->empty() == false && "need to check empty() before take()ing" );
00126             t = mPool.front();
00127             mPool.pop_front();
00128             ++mNumCheckedOut;
00129          this->release();
00130       }
00131    
00135       void putback( type* t )
00136       {
00137          this->acquire();
00138          {
00139             if (mPool.size() < mSize)
00140                mPool.push_front( t );
00141    
00142             // resize was called, and this is our lazy way of 
00143             // deleting the extra flyweight...
00144             else
00145                delete t;
00146             
00147             --mNumCheckedOut;
00148          }
00149          this->release();
00150       }   
00151    
00152    private:
00153       void resize_nonthreadsafe( unsigned int s )
00154       {
00155          // compute deltas to grow or shrink
00156          int size_to_grow = (int)s - (int)mSize;
00157          int size_to_shrink = -size_to_grow;
00158          int x;
00159          
00160          // if user wants us to grow, add items to the pool
00161          for (x = 0; x < size_to_grow; ++x)
00162          {
00163             mPool.push_front( new type );
00164          }
00165          
00166          // if user wants us to shrink, remove items from the pool
00167          for (x = 0; x < size_to_shrink && mPool.size() > 0; ++x)
00168          {
00169             delete mPool.back();
00170             mPool.pop_back();
00171          }
00172          
00173          // resize is done, record the new size...
00174          mSize = s;
00175       }
00176    
00177 #ifdef HAVE_VPR
00178       mutable vpr::Mutex mMutex;
00179 #endif
00180       bool mAutoGrow;
00181       int mNumCheckedOut;
00182       unsigned int mSize;
00183       std::list<type*> mPool;
00184 
00185       
00186    };
00187    
00188 }
00189 #endif

Generated at Mon Apr 15 09:26:08 2002 for subsynth by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001