00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "../include/PCMThread.h"
00030
00031 namespace ParCompMark
00032 {
00033
00034
00035
00036
00037
00038 Thread::Thread(const std::string & name)
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 {
00053 mThreadName = name;
00054 mWait = new bool;
00055 *mWait.getPtr() = false;
00056 mStopRequested = false;
00057 mRunning = false;
00058 mThread = 0;
00059 mJoinable = false;
00060
00061 if(0 != pthread_cond_init(&mCondition, 0))
00062 {
00063 Except(INTERNAL_ERROR, "Thread::wait()", "Unable to init condition variable.");
00064 }
00065 if(0 != pthread_mutex_init(&mConditionMutex, 0))
00066 {
00067 Except(INTERNAL_ERROR, "Thread::wait()", "Unable to init mutex variable.");
00068 }
00069
00070 mCurrentFPS = 0;
00071 mExpectedFPS = 0;
00072 mIterationNumber = 0;
00073 }
00074
00075
00076
00077 Thread::~Thread()
00078 {
00079 pthread_mutex_destroy(&mConditionMutex);
00080 pthread_cond_destroy(&mCondition);
00081
00082 if(mRunning)
00083 shutDownThread();
00084
00085 Logger::getInstance()->log(Logger::DEBUG, "Thread " + mThreadName + " is dying.");
00086
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 void *Thread::entryPoint(void *arg)
00096 {
00097
00098 Thread *pthis = (Thread *) arg;
00099
00100
00101 if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL))
00102 {
00103 Except(INTERNAL_ERROR, "Thread::entryPoint", "Unable to set cancel enabling");
00104 }
00105
00106 if(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL))
00107 {
00108 Except(INTERNAL_ERROR, "Thread::entryPoint", "Unable to set cancelling type");
00109 }
00110
00111 pthis->thread();
00112
00113 pthis->mRunning = false;
00114 Logger::getInstance()->log(Logger::DEBUG, "Thread " + pthis->mThreadName + " finished.");
00115
00116
00117 pthread_exit(0);
00118 }
00119
00120
00121
00122
00123
00124
00125
00126 void Thread::initThread(const u32 & iterationNumber, const u32 & expectedFPS,
00127 const bool & joinable, const bool & waitThread)
00128 {
00129 Assert(joinable || !waitThread, INVALID_OPERATION_ERROR, "Thread::initThread");
00130 Assert(!((waitThread) && iterationNumber == 0), INVALID_OPERATION_ERROR, "Thread::initThread");
00131
00132 mExpectedFPS = expectedFPS;
00133 mIterationNumber = iterationNumber;
00134 mJoinable = joinable;
00135 mWaitThread = waitThread;
00136 }
00137
00138
00139
00140 void Thread::threadInitialize()
00141 {
00142 }
00143
00144
00145
00146 void Thread::threadFinalize()
00147 {
00148 }
00149
00150
00151
00152 void Thread::startThread()
00153 {
00154
00155
00156 Assert(!mRunning, INVALID_OPERATION_ERROR, "Thread::startThread");
00157
00158 pthread_attr_t attr;
00159
00160
00161 pthread_attr_init(&attr);
00162
00163 if(mJoinable)
00164 {
00165 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
00166 } else
00167 {
00168 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00169 }
00170
00171
00172 mRunning = true;
00173 pthread_create(&mThread, &attr, &(Thread::entryPoint), (void *) this);
00174
00175 pthread_attr_destroy(&attr);
00176 Logger::getInstance()->log(Logger::DEBUG, "Thread " + mThreadName + " started.");
00177 }
00178
00179
00180
00181 void Thread::joinThread()
00182 {
00183
00184
00185
00186
00187 Assert(mJoinable, INVALID_OPERATION_ERROR, "Thread::joinThread()");
00188
00189 if(!mRunning)
00190 {
00191 return;
00192 }
00193
00194 if(pthread_join(mThread, 0))
00195 {
00196 Except(INTERNAL_ERROR, "Thread::joinThread()", "Unable to join thread " + mThreadName);
00197 }
00198
00199 }
00200
00201
00202
00203 void Thread::shutDownThread()
00204 {
00205
00206 Assert(mRunning, INVALID_OPERATION_ERROR, "Thread::shutDownThread()");
00207 Assert(mThread, NULL_POINTER_ERROR, "Thread::shutDownThread()");
00208 Logger::getInstance()->log(Logger::DEBUG, "Thread " + mThreadName + " is going down.");
00209
00210
00211
00212 if(mWaitThread)
00213 {
00214 if(pthread_join(mThread, 0))
00215 {
00216 Except(INTERNAL_ERROR, "Thread::shutDownThread()", "Unable join thread " + mThreadName);
00217 }
00218 } else
00219 {
00220 if(pthread_cancel(mThread))
00221 {
00222 Except(INTERNAL_ERROR, "Thread::shutDownThread()", "Unable to shut down thread " + mThreadName);
00223 }
00224 }
00225
00226 mStopRequested = false;
00227 mRunning = false;
00228 mThread = 0;
00229 Logger::getInstance()->log(Logger::DEBUG, "Thread " + mThreadName + " is down.");
00230 }
00231
00232
00233
00234 void Thread::stopThread()
00235 {
00236 Logger::getInstance()->log(Logger::DEBUG, "Stopping " + mThreadName);
00237 mStopRequested = true;
00238 }
00239
00240
00241
00242 void Thread::go()
00243 {
00244
00245 if(pthread_mutex_lock(&mConditionMutex) != 0)
00246 {
00247 Except(INTERNAL_ERROR, "Thread::go", "??? can't lock");
00248 }
00249
00250 if(pthread_cond_signal(&mCondition) != 0)
00251 {
00252 Except(INTERNAL_ERROR, "Thread::go", "??? can't go");
00253 }
00254
00255 if(pthread_mutex_unlock(&mConditionMutex) != 0)
00256 {
00257 Except(INTERNAL_ERROR, "Thread::go", "??? can't unlock");
00258 }
00259
00260 }
00261
00262
00263
00264 void Thread::thread()
00265 {
00266 threadInitialize();
00267
00268 yield();
00269
00270 if(mIterationNumber == 0)
00271
00272 for(;;)
00273 {
00274
00275 if(iteration())
00276 break;
00277 }
00278
00279 else
00280
00281 for(u32 i = 0; i < mIterationNumber; i++)
00282 {
00283 if(iteration())
00284 break;
00285 }
00286
00287 threadFinalize();
00288
00289 yield();
00290
00291 }
00292
00293
00294
00295 void Thread::task()
00296 {
00297
00298
00299 Timer::sleep(0.01);
00300
00301 }
00302
00303
00304
00305 void Thread::wait()
00306 {
00307
00308 if(pthread_mutex_lock(&mConditionMutex) != 0)
00309 {
00310 Except(INTERNAL_ERROR, "Thread::wait", "??? can't lock");
00311 }
00312
00313 if(pthread_cond_wait(&mCondition, &mConditionMutex) != 0)
00314 {
00315 Except(INTERNAL_ERROR, "Thread::wait", "??? can't cond_wait");
00316 }
00317
00318 if(pthread_mutex_unlock(&mConditionMutex) != 0)
00319 {
00320 Except(INTERNAL_ERROR, "Thread::wait", "??? can't unlock");
00321 }
00322
00323 }
00324
00325
00326
00327 }