base_thread.hh

Go to the documentation of this file.
00001 /*
00053  * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
00054  *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
00055  *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
00056  *****************************************************************************/
00057 
00058 #if COMPILE_THREADS
00059 #ifndef BASE_THREAD_HH
00060 #define BASE_THREAD_HH 1
00061 
00062 #include "base_thread_common.hh"
00063 
00064 namespace base {
00065 
00066 // Abbrev:
00067 #define gThread base::global.mThread
00068 
00069 // Function decorations:
00070 #define FN_MAIN_THREAD  // means only the MAIN thread can execute function
00071 #define FN_REENTRANT    // function is threadable without locking
00072 #define FN_LOCKED       // function is threadable but must be locked
00073 
00074 // Macros:
00075 #define THREAD_CODE( CODE ) CODE
00076 #define THREAD_RUN( func, funcArg, priority ) gThread.Run( (func), (funcArg), (priority) )
00077 
00078 void* SuballocateThreadMemory( const uint bytes );  // solves compiling dependency
00079 
00085 class Thread : public Threadable
00086 {
00087 
00088 friend void* SuballocateThreadMemory( const uint bytes );
00089 
00090 public:
00091     typedef void(*ThreadFunc)(long);  
00092     enum ePriority { ePriority_DEFAULT, ePriority_LOW, ePriority_HIGH, };  
00093 
00094 public:
00098     struct Tid
00099     {
00100     private:
00101         Tid( pthread_t tidPthread ) : mPthread(tidPthread) { }
00102         pthread_t   mPthread;  // POSIX pthread ID
00103     friend class Thread;
00104     };
00105 
00106 public:
00113     struct RunArgs
00114     {
00115         RunArgs( ThreadFunc        func,
00116                  long              funcArg,
00117                  Thread::ePriority priority         = Thread::ePriority_DEFAULT,
00118                  uint              threadMemorySize = base::defs::DEFAULT_THREAD_MEMORY_SIZE,
00119                  bool              joinable         = false );
00120 
00121         ThreadFunc          mFunc;              
00122         long                mFuncArg;           
00123         Thread::ePriority   mPriority;          
00124         uint                mThreadMemorySize;  
00125         bool                mJoinable;          
00126     };
00127 
00128 public:
00132     class Condition
00133     {
00134     friend class Thread;
00135     public:
00136         Condition( void );
00137         ~Condition();
00138     private:
00139         pthread_cond_t  mCondition;; 
00140         pthread_mutex_t mMutex;
00141     };
00142 
00143 private:
00144     friend class Global;
00145     Thread( void );
00146     ~Thread();
00147 
00148 public:
00149     Tid         Run( const RunArgs& runArgs );
00150     void        Yield( void );
00151     void        Sleep( Milliseconds millisecs );
00152     bool        Wait( Tid tid );
00153     void        Wait( Condition& condition );
00154     void        Awaken( Condition& condition );
00155     uint        Cnt( void );
00156     bool        IfMain( void );
00157     Tid         GetTid( void );
00158     void*       SuballocateThreadMemory( uint bytes );
00159 
00160 private:
00161     void                InitPthreadAttr();
00162     CLASS_METHOD void*  Run2( void* runArgs );
00163     void                Run3( const RunArgs& runArgs );
00164     void                NewThreadMemory( const uint threadMemorySize );
00165     void                DeleteThreadMemory( void );
00166 
00167 private:
00168 #if DEBUG
00169     bool                    mValid;
00170 #endif
00171     Atomic::Int             mThreadCnt;         
00172     Tid                     mMainTid;           
00173     vector<pthread_attr_t>  mPthreadAttr;       
00174     pthread_key_t           mThreadMemoryKey;   
00175     CLASS_VAR uint          msDefaultThreadMemorySize;  
00176 
00177 //..............................................................................
00178 
00179 // Compatibility macros to help write locking code involving atomic TIDs
00180 // based on either gcc Thread Local Storage (TLS) or generic pthreads.
00181 // An "atomic TID" is meant to be an operand in atomic operations for locking.
00182 // Don't confuse an atomic TID with with a pthreads TID.
00183 // class FastLock
00184 // {
00185 //     void Lock( void )
00186 //     {
00187 //         mOwner = THREAD_ATOMIC_TID();
00188 //         if ( THREAD_ATOMIC_TID_EQUAL(mOwner) )
00189 //     }
00190 //     Thread::AtomicTid  mOwner;
00191 // };
00192 // Atomic TID is a thread-local variable.
00193 // A new thread receives an "atomic TID" then
00194 // the Thread class increments it for the next thread.
00195 #if COMPILE_GCC_TLS
00196 #define THREAD_ATOMIC_TID()             (restrict::gAtomicTid)
00197 #define THREAD_ATOMIC_TID_EQUAL(TID)    ((THREAD_ATOMIC_TID()) == (TID))
00198 public:  typedef volatile Atomic::Int   AtomicTid;
00199 private: CLASS_VAR int                  msAtomicTidNext;
00200 #else
00201 #define THREAD_ATOMIC_TID()             ( pthread_self() )
00202 #define THREAD_ATOMIC_TID_EQUAL(TID)    ( pthread_equal( pthread_self(), (TID) ) )
00203 public:  typedef volatile pthread_t     AtomicTid;
00204 #endif
00205 
00206 };
00207 
00208 //------------------------------------------------------------------------------
00209 
00210 #if COMPILE_GCC_TLS
00211 // On FreeBSD 6.2, __thread malfunctions as a class member.
00212 // __thread and volatile aren't compatible.
00213 namespace restrict { extern __thread int gAtomicTid; }
00214 #endif
00215 
00216 } // namespace base
00217 
00218 #endif // BASE_THREAD_HH
00219 #endif // COMPILE_THREADS
Palomino 3D Engine documents generated by doxygen 1.5.3 on Fri Nov 23 11:26:07 2007