base_thread_per.hh

Go to the documentation of this file.
00001 /*
00008  * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
00009  *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
00010  *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
00011  *****************************************************************************/
00012 
00013 #if COMPILE_THREADS
00014 #ifndef BASE_THREAD_PER_HH
00015 #define BASE_THREAD_PER_HH 1
00016 
00017 #include "base_thread_common.hh"
00018 
00019 namespace base {
00020 
00053 template<typename T>
00054 class PerThreadPtr
00055 {
00056   // two PerThreadPtrs can't share the same key
00057 public: 
00058     PerThreadPtr( void )
00059     {
00060         PTHREAD_CALL( pthread_key_create( &mKey, 0 ) );
00061         NewPerThreadVar();
00062     }
00063 
00064 private:
00065     // Allocate a new thread variable in per-thread memory.
00066     T* NewPerThreadVar( void )
00067     {
00068         // Suballocate thread memory (thread local storage).
00069         extern void* SuballocateThreadMemory( const uint bytes );  // solves compiling dependency
00070         void* objMem = SuballocateThreadMemory( sizeof(T) );
00071 
00072         // Use C++ "placement new" to place a new object in per-thread memory.
00073         T* obj = new (objMem) T;
00074 
00075         // Use a pthreads key to map pointer and this thread.
00076         PTHREAD_CALL( pthread_setspecific( mKey, obj ) );
00077         return obj;
00078     }
00079 
00080 public:
00081     ~PerThreadPtr()
00082     {
00083         PTHREAD_CALL( pthread_key_delete( mKey ) );
00084     }
00085 
00087     T* operator->( void )
00088     {
00089         T* threadVar = reinterpret_cast<T*>( pthread_getspecific( mKey ) );
00090         if ( EX( threadVar != NULL ) )
00091         {
00092             return threadVar;
00093         }
00094         else
00095         {
00096             // pthread_getspecific() returned NULL.
00097             // This (probably) means a new thread has started,
00098             // so allocate its own memory block on the heap object.
00099             return NewPerThreadVar();
00100         }
00101     }
00102 
00104     T& operator*( void )
00105     {
00106         return *operator->();
00107     }
00108 
00110     T* PTR( void )
00111     {
00112         return operator->();
00113     }
00114 
00115 private:
00116     pthread_key_t   mKey;
00117 };
00118 
00119 } // namespace base
00120 
00121 #endif // BASE_THREAD_PER_HH
00122 #endif // COMPILE_THREADS
Palomino 3D Engine documents generated by doxygen 1.5.3 on Fri Nov 23 11:26:07 2007