00001
00053
00054
00055
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
00067 #define gThread base::global.mThread
00068
00069
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
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 );
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;
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
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
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
00212
00213 namespace restrict { extern __thread int gAtomicTid; }
00214 #endif
00215
00216 }
00217
00218 #endif // BASE_THREAD_HH
00219 #endif // COMPILE_THREADS