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 }