00001 #ifndef THREADSPECIFICRANDOMENGINE_H_ 00002 #define THREADSPECIFICRANDOMENGINE_H_ 00003 00004 #include "RandomEngine.h" 00005 #include <boost/thread/tss.hpp> 00006 #include <boost/thread/mutex.hpp> 00007 00008 //#include <iostream> 00009 //using std::cerr; 00010 //using std::cout; 00011 //using std::endl; 00012 00013 typedef MersenneTwister19937 ThreadSpecificRandomEngineType; 00014 00015 class ThreadSpecificRandomEngine 00016 { 00017 public: 00018 ThreadSpecificRandomEngine() : 00019 tsp(cleanup), 00020 alloc_ptr(0) 00021 { /* NOOP */ } 00022 00023 virtual ~ThreadSpecificRandomEngine() 00024 { 00025 free_ptr(); 00026 } 00027 00028 void free_ptr(void) { 00029 boost::mutex::scoped_lock scoped_lock(mutex); 00030 for( size_t i=0; i<alloc_ptr.size(); i++ ) { 00031 if( alloc_ptr[i] != NULL ) delete alloc_ptr[i]; 00032 alloc_ptr[i] = NULL; 00033 } 00034 } 00035 00037 void init(void) 00038 { 00039 RandomEngine *eng = tsp.get(); 00040 if( eng == NULL ) { 00041 boost::mutex::scoped_lock scoped_lock(mutex); 00042 eng = new ThreadSpecificRandomEngineType; 00043 //cerr << "ThreadSpecificRandomEngine::init: new engine " << dis << " allocated\n\n" ; 00044 tsp.reset( eng ); 00045 alloc_ptr.push_back( eng ); 00046 } 00047 } 00048 00050 void set( RandomEngine *eng ) 00051 { 00052 tsp.reset( eng ); 00053 //cerr << "ThreadSpecificRandomEngine::set: new engine " << eng << " set\n\n" ; 00054 } 00055 00057 void unset( RandomEngine *eng ) 00058 { 00059 tsp.release(); 00060 init(); 00061 } 00062 00064 00066 RandomEngine *get(void ) 00067 { 00068 return tsp.get(); 00069 } 00070 00071 00072 private: 00073 boost::thread_specific_ptr< RandomEngine > tsp; 00074 boost::mutex mutex; 00075 std::vector< RandomEngine * > alloc_ptr; 00076 static void cleanup( RandomEngine *e ) { }; 00077 }; 00078 00079 extern ThreadSpecificRandomEngine theThreadSpecificRandomEngine; 00080 00081 00082 #endif /*THREADSPECIFICRANDOMENGINE_H_*/