ThreadSpecificRandomDistribution.h

Go to the documentation of this file.
00001 #ifndef THREADSPECIFICRANDOMDISTRIBUTION_H_
00002 #define THREADSPECIFICRANDOMDISTRIBUTION_H_
00003 
00004 #include "ThreadSpecificRandomEngine.h"
00005 #include "RandomDistribution.h"
00006 
00007 template< class Dist >
00008 class ThreadSpecificRandomDistribution
00009 {
00010 public:
00011 
00012     ThreadSpecificRandomDistribution( void ) :
00013             tsp(cleanup),
00014             alloc_ptr(0)
00015     {
00016         init();
00017     }
00018 
00019     ThreadSpecificRandomDistribution( Dist const& d ) :
00020             tsp(cleanup),
00021             alloc_ptr(0),
00022             dist_model(d)
00023     {
00024         init();
00025     }
00026 
00027     virtual ~ThreadSpecificRandomDistribution()
00028     {
00029         free_ptr();
00030     }
00031 
00032     void free_ptr(void) {
00033         boost::mutex::scoped_lock scoped_lock(mutex);
00034         for( size_t i=0; i<alloc_ptr.size(); i++ ) {
00035             if( alloc_ptr[i] != NULL ) delete alloc_ptr[i];
00036             alloc_ptr[i] = NULL;
00037         }
00038     }
00039 
00040     void init(void)
00041     {
00042         Dist *var = tsp.get();
00043         if( var == NULL ) {
00044             boost::mutex::scoped_lock scoped_lock(mutex);
00045             var = new Dist( dist_model );
00046             tsp.reset( var );
00047             alloc_ptr.push_back( var );
00048             //cerr << "ThreadSpecificRandomDistribution::init: new distribution " << typeid( Dist ).name() << " allocated: ptr=" << var << ", size=" << alloc_ptr.size() << "\n\n" ;
00049             theThreadSpecificRandomEngine.init();
00050         }
00051     }
00052 
00053     void set( Dist const& d )
00054     {
00055         Dist *var = tsp.get();
00056         if( var != NULL ) {
00057             *var = dist_model = d; // the distribution pointed to by var is overwritten with d
00058             //cerr << "ThreadSpecificRandomDistribution::set: dist " << var << " set\n\n" ;
00059         } else {
00060             dist_model = d;
00061             init();
00062         }
00063         theThreadSpecificRandomEngine.init();
00064     }
00065 
00066     double operator()(void)
00067     {
00068         // cerr << "operator(): dist= " << tsp.get() <<  ", eng=" << theThreadSpecificRandomEngine.get() << "\n";
00069         return (*tsp.get())( *theThreadSpecificRandomEngine.get() );
00070     }
00071 
00072 private:
00073     boost::thread_specific_ptr< Dist > tsp;
00074     boost::mutex mutex;
00075     std::vector< Dist * > alloc_ptr;
00076     static void cleanup( Dist *d ) { };
00077     Dist dist_model;
00078 };
00079 
00080 #endif /*THREADSPECIFICRANDOMDISTRIBUTION_H_*/

Generated on Wed Jul 9 16:34:39 2008 for PCSIM by  doxygen 1.5.5