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
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;
00058
00059 } else {
00060 dist_model = d;
00061 init();
00062 }
00063 theThreadSpecificRandomEngine.init();
00064 }
00065
00066 double operator()(void)
00067 {
00068
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