Cbc trunk
|
00001 /* $Id: CbcThread.hpp 1221 2009-09-03 15:43:48Z forrest $ */ 00002 // Copyright (C) 2009, International Business Machines 00003 // Corporation and others. All Rights Reserved. 00004 // This code is licensed under the terms of the Eclipse Public License (EPL). 00005 00006 #ifndef CbcThread_H 00007 #define CbcThread_H 00008 00009 #include "CbcModel.hpp" 00010 #include "CbcNode.hpp" 00011 class OsiObject; 00012 class OsiCuts; 00013 #ifdef CBC_THREAD 00014 class CbcThread; 00015 // Use pthreads 00016 #define CBC_PTHREAD 00017 #ifdef CBC_PTHREAD 00018 #include <pthread.h> 00019 typedef struct { 00020 pthread_t thr; 00021 long status; 00022 } Coin_pthread_t; 00023 #endif 00024 //#define THREAD_DEBUG 1 00033 class CbcSpecificThread { 00034 public: 00035 // Default Constructor 00036 CbcSpecificThread (); 00037 00038 // Useful Constructor 00039 CbcSpecificThread (CbcSpecificThread * master, pthread_mutex_t * masterMutex); 00040 00041 virtual ~CbcSpecificThread(); 00042 00043 // Useful stuff 00044 void setUsefulStuff (CbcSpecificThread * master, 00045 void *& masterMutex); 00050 void lockThread(); 00054 void unlockThread(); 00056 void lockThread2(bool doAnyway = false); 00058 void unlockThread2(bool doAnyway = false); 00060 void signal(); 00062 void timedWait(int time); 00064 void startThread(void * (*routine ) (void *), CbcThread * thread); 00066 int exit(); 00068 void exitThread(); 00070 int status() const; 00072 void setStatus(int value); 00073 //} 00074 00075 00076 public: // private: 00077 CbcSpecificThread * basePointer_; // for getting main mutex and threadid of base 00078 #ifdef CBC_PTHREAD 00079 pthread_mutex_t *masterMutex_; // for synchronizing 00080 pthread_mutex_t mutex2_; // for waking up threads 00081 pthread_cond_t condition2_; // for waking up thread 00082 Coin_pthread_t threadId_; 00083 #endif 00084 bool locked_; // For mutex2 00085 }; 00089 class CbcThread { 00090 private: 00091 void gutsOfDelete(); 00092 void gutsOfCopy(const CbcThread & rhs); 00093 00094 public: 00095 // Default Constructor 00096 CbcThread (); 00097 00098 virtual ~CbcThread(); 00099 00101 void setUsefulStuff (CbcModel * model, int deterministic, 00102 CbcModel * baseModel, 00103 CbcThread * master, 00104 void *& masterMutex); 00109 void lockThread(); 00113 void unlockThread(); 00114 00116 inline bool isLocked() const { 00117 return locked_; 00118 } 00123 bool wait(int type, int currentCode); 00125 void waitNano(int time); 00127 void signal(); 00129 void lockFromMaster(); 00131 void unlockFromMaster(); 00133 void lockFromThread(); 00135 void unlockFromThread(); 00137 int exit(); 00139 void exitThread(); 00141 void waitThread(); 00143 inline int status() const { 00144 return threadStuff_.status(); 00145 } 00147 inline void setStatus(int value) { 00148 threadStuff_.setStatus( value); 00149 } 00151 inline int returnCode() const { 00152 return returnCode_; 00153 } 00155 inline void setReturnCode(int value) { 00156 returnCode_ = value; 00157 } 00159 inline CbcModel * baseModel() const { 00160 return baseModel_; 00161 } 00163 inline CbcModel * thisModel() const { 00164 return thisModel_; 00165 } 00167 inline CbcNode * node() const { 00168 return node_; 00169 } 00171 inline void setNode(CbcNode * node) { 00172 node_ = node; 00173 } 00175 inline CbcNode * createdNode() const { 00176 return createdNode_; 00177 } 00179 inline void setCreatedNode(CbcNode * node) { 00180 createdNode_ = node; 00181 } 00183 inline int dantzigState() const { 00184 return dantzigState_; 00185 } 00187 inline void setDantzigState(int value) { 00188 dantzigState_ = value; 00189 } 00191 inline double timeInThread() const { 00192 return timeInThread_; 00193 } 00195 inline void incrementTimeInThread(double value) { 00196 timeInThread_ += value; 00197 } 00199 inline double timeWaitingToStart() const { 00200 return timeWaitingToStart_; 00201 } 00203 inline void incrementTimeWaitingToStart(double value) { 00204 timeWaitingToStart_ += value; 00205 } 00207 inline double timeLocked() const { 00208 return timeLocked_; 00209 } 00211 inline void incrementTimeLocked(double value) { 00212 timeLocked_ += value; 00213 } 00215 inline double timeWaitingToLock() const { 00216 return timeWaitingToLock_; 00217 } 00219 inline void incrementTimeWaitingToLock(double value) { 00220 timeWaitingToLock_ += value; 00221 } 00223 inline int deterministic() const { 00224 return deterministic_; 00225 } 00227 inline int maxDeleteNode() const { 00228 return maxDeleteNode_; 00229 } 00231 inline void setMaxDeleteNode(int value) { 00232 maxDeleteNode_ = value; 00233 } 00235 inline int nDeleteNode() const { 00236 return nDeleteNode_; 00237 } 00239 inline void setNDeleteNode(int value) { 00240 nDeleteNode_ = value; 00241 } 00243 inline void clearDelNode() { 00244 delete delNode_; 00245 delNode_ = NULL; 00246 } 00248 inline void fakeDelNode(CbcNode ** delNode) { 00249 delNode_ = delNode; 00250 } 00252 inline CbcNode ** delNode() const { 00253 return delNode_; 00254 } 00256 inline void setDelNode(CbcNode ** delNode) { 00257 delNode_ = delNode; 00258 } 00260 inline int numberTimesLocked() const { 00261 return numberTimesLocked_; 00262 } 00264 inline int numberTimesUnlocked() const { 00265 return numberTimesUnlocked_; 00266 } 00268 inline int nodesThisTime() const { 00269 return nodesThisTime_; 00270 } 00272 inline void setNodesThisTime(int value) { 00273 nodesThisTime_ = value; 00274 } 00276 inline int iterationsThisTime() const { 00277 return iterationsThisTime_; 00278 } 00280 inline void setIterationsThisTime(int value) { 00281 iterationsThisTime_ = value; 00282 } 00284 inline int * saveStuff() { 00285 return saveStuff_; 00286 } 00288 inline bool locked() const { 00289 return locked_; 00290 } 00291 00292 public: // private: 00293 CbcSpecificThread threadStuff_; 00294 CbcModel * baseModel_; 00295 CbcModel * thisModel_; 00296 CbcNode * node_; // filled in every time 00297 CbcNode * createdNode_; // filled in every time on return 00298 CbcThread * master_; // points back to master thread 00299 int returnCode_; // -1 available, 0 busy, 1 finished , 2?? 00300 double timeLocked_; 00301 double timeWaitingToLock_; 00302 double timeWaitingToStart_; 00303 double timeInThread_; 00304 double timeWhenLocked_; // time when thread got lock (in seconds) 00305 int numberTimesLocked_; 00306 int numberTimesUnlocked_; 00307 int numberTimesWaitingToStart_; 00308 int saveStuff_[2]; 00309 int dantzigState_; // 0 unset, -1 waiting to be set, 1 set 00310 bool locked_; 00311 int nDeleteNode_; 00312 CbcNode ** delNode_; 00313 int maxDeleteNode_; 00314 int nodesThisTime_; 00315 int iterationsThisTime_; 00316 int deterministic_; 00317 #ifdef THREAD_DEBUG 00318 public: 00319 int threadNumber_; 00320 int lockCount_; 00321 #endif 00322 }; 00326 class CbcBaseModel { 00327 public: 00328 // Default Constructor 00329 CbcBaseModel (); 00330 00339 CbcBaseModel (CbcModel & model, int type); 00340 00341 virtual ~CbcBaseModel(); 00342 00347 void stopThreads(int type); 00348 00355 int waitForThreadsInTree(int type); 00356 00361 void waitForThreadsInCuts(int type, OsiCuts * eachCuts, int whichGenerator); 00362 00364 void deterministicParallel(); 00369 inline void lockThread() { 00370 children_[numberThreads_].lockThread(); 00371 } 00375 inline void unlockThread() { 00376 children_[numberThreads_].unlockThread(); 00377 } 00378 00380 inline bool isLocked() const { 00381 return children_[numberThreads_].locked(); 00382 } 00383 00385 CbcThread * masterThread() const; 00386 00388 inline CbcModel * model(int i) const { 00389 return threadModel_[i]; 00390 } 00391 00393 void setDantzigState(); 00394 00395 private: 00396 00398 int numberThreads_; 00400 CbcThread * children_; 00404 int type_; 00405 int * threadCount_; 00406 CbcModel ** threadModel_; 00407 int numberObjects_; 00408 OsiObject ** saveObjects_; 00409 int threadStats_[6]; 00410 int defaultParallelIterations_; 00411 int defaultParallelNodes_; 00412 }; 00413 #else 00414 // Dummy threads 00418 class CbcThread { 00419 public: 00420 // Default Constructor 00421 CbcThread () {} 00422 00423 virtual ~CbcThread() {} 00424 00425 }; 00429 class CbcBaseModel { 00430 public: 00431 // Default Constructor (not declared here so that CbcThread.cpp not empty) 00432 CbcBaseModel (); 00433 00434 virtual ~CbcBaseModel() {} 00435 00436 }; 00437 #endif 00438 00439 #endif 00440