source: trunk/Cbc/src/CbcThread.hpp

Last change on this file was 2465, checked in by unxusr, 10 months ago

script to format sources

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.0 KB
RevLine 
[1854]1/* $Id: CbcThread.hpp 2465 2019-01-03 19:26:52Z glebb $ */
[1404]2// Copyright (C) 2009, International Business Machines
3// Corporation and others.  All Rights Reserved.
[1573]4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
[1404]6#ifndef CbcThread_H
7#define CbcThread_H
8
9#include "CbcModel.hpp"
10#include "CbcNode.hpp"
11class OsiObject;
[1409]12class OsiCuts;
13#ifdef CBC_THREAD
[1412]14class CbcThread;
15// Use pthreads
16#define CBC_PTHREAD
17#ifdef CBC_PTHREAD
[1409]18#include <pthread.h>
19typedef struct {
[2464]20  pthread_t thr;
21  long status;
[1409]22} Coin_pthread_t;
23#endif
[1412]24//#define THREAD_DEBUG 1
25/** A class to encapsulate specific thread stuff
26    To use another api with same style - you just need to implement
27    these methods.
[1409]28
[1412]29    At present just pthreads
30 */
[1409]31
[1412]32class CbcSpecificThread {
[1409]33public:
[2464]34  // Default Constructor
35  CbcSpecificThread();
[1409]36
[2464]37  // Useful Constructor
38  CbcSpecificThread(CbcSpecificThread *master, pthread_mutex_t *masterMutex);
[1409]39
[2464]40  virtual ~CbcSpecificThread();
[1409]41
[2464]42  // Useful stuff
43  void setUsefulStuff(CbcSpecificThread *master,
44    void *&masterMutex);
45  /**
[1409]46       Locks a thread if parallel so that stuff like cut pool
47       can be updated and/or used.
48    */
[2464]49  void lockThread();
50  /**
[1409]51       Unlocks a thread if parallel to say cut pool stuff not needed
52    */
[2464]53  void unlockThread();
54  ///  Locks a thread for testing whether to start etc
55  void lockThread2(bool doAnyway = false);
56  ///  Unlocks a thread for testing whether to start etc
57  void unlockThread2(bool doAnyway = false);
58  /// Signal
59  void signal();
60  /// Timed wait in nanoseconds - if negative then seconds
61  void timedWait(int time);
62  /// Actually starts a thread
63  void startThread(void *(*routine)(void *), CbcThread *thread);
64  /// Exits thread (called from master) - return code should be zero
65  int exit();
66  /// Exits thread
67  void exitThread();
68  /// Get status
69  int status() const;
70  /// Set status
71  void setStatus(int value);
72  //}
[1409]73
[1412]74public: // private:
[2464]75  CbcSpecificThread *basePointer_; // for getting main mutex and threadid of base
[1412]76#ifdef CBC_PTHREAD
[2464]77  pthread_mutex_t *masterMutex_; // for synchronizing
78  pthread_mutex_t mutex2_; // for waking up threads
79  pthread_cond_t condition2_; // for waking up thread
80  Coin_pthread_t threadId_;
[1412]81#endif
[2464]82  bool locked_; // For mutex2
[1409]83};
[1404]84/** A class to encapsulate thread stuff */
85
86class CbcThread {
87private:
[2464]88  void gutsOfDelete();
89  void gutsOfCopy(const CbcThread &rhs);
[1404]90
91public:
[2464]92  // Default Constructor
93  CbcThread();
[1404]94
[2464]95  virtual ~CbcThread();
[1404]96
[2464]97  /// Fills in useful stuff
98  void setUsefulStuff(CbcModel *model, int deterministic,
99    CbcModel *baseModel,
100    CbcThread *master,
101    void *&masterMutex);
102  /**
[1409]103       Locks a thread if parallel so that stuff like cut pool
104       can be updated and/or used.
105    */
[2464]106  void lockThread();
107  /**
[1409]108       Unlocks a thread if parallel to say cut pool stuff not needed
109    */
[2464]110  void unlockThread();
[1409]111
[2464]112  /// Returns true if locked
113  inline bool isLocked() const
114  {
115    return locked_;
116  }
117  /** Wait for child to have return code NOT == to currentCode
[1412]118        type - 0 timed wait
119               1 wait
120           returns true if return code changed */
[2464]121  bool wait(int type, int currentCode);
122  /// Just wait for so many nanoseconds
123  void waitNano(int time);
124  /// Signal child to carry on
125  void signal();
126  /// Lock from master with mutex2 and signal before lock
127  void lockFromMaster();
128  /// Unlock from master with mutex2 and signal after unlock
129  void unlockFromMaster();
130  /// Lock from thread with mutex2 and signal before lock
131  void lockFromThread();
132  /// Unlock from thread with mutex2 and signal after unlock
133  void unlockFromThread();
134  /// Exits thread (called from master) - return code should be zero
135  int exit();
136  /// Exits thread
137  void exitThread();
138  /// Waits until returnCode_ goes to zero
139  void waitThread();
140  /// Get status
141  inline int status() const
142  {
143    return threadStuff_.status();
144  }
145  /// Set status
146  inline void setStatus(int value)
147  {
148    threadStuff_.setStatus(value);
149  }
150  /// Get return code
151  inline int returnCode() const
152  {
153    return returnCode_;
154  }
155  /// Set return code
156  inline void setReturnCode(int value)
157  {
158    returnCode_ = value;
159  }
160  /// Get base model
161  inline CbcModel *baseModel() const
162  {
163    return baseModel_;
164  }
165  /// Get this model
166  inline CbcModel *thisModel() const
167  {
168    return thisModel_;
169  }
170  /// Get node
171  inline CbcNode *node() const
172  {
173    return node_;
174  }
175  /// Set node
176  inline void setNode(CbcNode *node)
177  {
178    node_ = node;
179  }
180  /// Get created node
181  inline CbcNode *createdNode() const
182  {
183    return createdNode_;
184  }
185  /// Set created node
186  inline void setCreatedNode(CbcNode *node)
187  {
188    createdNode_ = node;
189  }
190  /// Get dantzig state
191  inline int dantzigState() const
192  {
193    return dantzigState_;
194  }
195  /// Set dantzig state
196  inline void setDantzigState(int value)
197  {
198    dantzigState_ = value;
199  }
200  /// Get time in thread
201  inline double timeInThread() const
202  {
203    return timeInThread_;
204  }
205  /// Increment time in thread
206  inline void incrementTimeInThread(double value)
207  {
208    timeInThread_ += value;
209  }
210  /// Get time waiting to start
211  inline double timeWaitingToStart() const
212  {
213    return timeWaitingToStart_;
214  }
215  /// Increment time waiting to start
216  inline void incrementTimeWaitingToStart(double value)
217  {
218    timeWaitingToStart_ += value;
219  }
220  /// Get time locked
221  inline double timeLocked() const
222  {
223    return timeLocked_;
224  }
225  /// Increment time locked
226  inline void incrementTimeLocked(double value)
227  {
228    timeLocked_ += value;
229  }
230  /// Get time waiting to lock
231  inline double timeWaitingToLock() const
232  {
233    return timeWaitingToLock_;
234  }
235  /// Increment time waiting to lock
236  inline void incrementTimeWaitingToLock(double value)
237  {
238    timeWaitingToLock_ += value;
239  }
240  /// Get if deterministic
241  inline int deterministic() const
242  {
243    return deterministic_;
244  }
245  /// Get maxDeleteNode
246  inline int maxDeleteNode() const
247  {
248    return maxDeleteNode_;
249  }
250  /// Set maxDeleteNode
251  inline void setMaxDeleteNode(int value)
252  {
253    maxDeleteNode_ = value;
254  }
255  /// Get nDeleteNode (may be fake i.e. defaultParallelIterations_)
256  inline int nDeleteNode() const
257  {
258    return nDeleteNode_;
259  }
260  /// Set nDeleteNode (may be fake i.e. defaultParallelIterations_)
261  inline void setNDeleteNode(int value)
262  {
263    nDeleteNode_ = value;
264  }
265  /// Clear delNode
266  inline void clearDelNode()
267  {
268    delete delNode_;
269    delNode_ = NULL;
270  }
271  /// Set fake delNode to pass across OsiCuts
272  inline void fakeDelNode(CbcNode **delNode)
273  {
274    delNode_ = delNode;
275  }
276  /// Get delNode
277  inline CbcNode **delNode() const
278  {
279    return delNode_;
280  }
281  /// Set delNode
282  inline void setDelNode(CbcNode **delNode)
283  {
284    delNode_ = delNode;
285  }
286  /// Get number times locked
287  inline int numberTimesLocked() const
288  {
289    return numberTimesLocked_;
290  }
291  /// Get number times unlocked
292  inline int numberTimesUnlocked() const
293  {
294    return numberTimesUnlocked_;
295  }
296  /// Get number of nodes this time
297  inline int nodesThisTime() const
298  {
299    return nodesThisTime_;
300  }
301  /// Set number of nodes this time
302  inline void setNodesThisTime(int value)
303  {
304    nodesThisTime_ = value;
305  }
306  /// Get number of iterations this time
307  inline int iterationsThisTime() const
308  {
309    return iterationsThisTime_;
310  }
311  /// Set number of iterations this time
312  inline void setIterationsThisTime(int value)
313  {
314    iterationsThisTime_ = value;
315  }
316  /// Get save stuff array
317  inline int *saveStuff()
318  {
319    return saveStuff_;
320  }
321  /// Say if locked
322  inline bool locked() const
323  {
324    return locked_;
325  }
[1409]326
[1412]327public: // private:
[2464]328  CbcSpecificThread threadStuff_;
329  CbcModel *baseModel_;
330  CbcModel *thisModel_;
331  CbcNode *node_; // filled in every time
332  CbcNode *createdNode_; // filled in every time on return
333  CbcThread *master_; // points back to master thread
334  int returnCode_; // -1 available, 0 busy, 1 finished , 2??
335  double timeLocked_;
336  double timeWaitingToLock_;
337  double timeWaitingToStart_;
338  double timeInThread_;
339  double timeWhenLocked_; // time when thread got lock (in seconds)
340  int numberTimesLocked_;
341  int numberTimesUnlocked_;
342  int numberTimesWaitingToStart_;
343  int saveStuff_[2];
344  int dantzigState_; // 0 unset, -1 waiting to be set, 1 set
345  bool locked_;
346  int nDeleteNode_;
347  CbcNode **delNode_;
348  int maxDeleteNode_;
349  int nodesThisTime_;
350  int iterationsThisTime_;
351  int deterministic_;
[1412]352#ifdef THREAD_DEBUG
353public:
[2464]354  int threadNumber_;
355  int lockCount_;
[1412]356#endif
[1404]357};
[1409]358/** Base model */
[1404]359
[1409]360class CbcBaseModel {
361public:
[2464]362  // Default Constructor
363  CbcBaseModel();
[1409]364
[2464]365  /** Constructor with model
[1409]366        type -1 cuts
367              0 opportunistic
368              1 deterministic */
[2464]369  /** Constructor with model
[1409]370        type -1 cuts
371              0 opportunistic
372              1 deterministic */
[2464]373  CbcBaseModel(CbcModel &model, int type);
[1409]374
[2464]375  virtual ~CbcBaseModel();
[1409]376
[2464]377  /** Stop all threads
[1412]378        -1 just check all in good state
379        0 actually stop
380    */
[2464]381  void stopThreads(int type);
[1409]382
[2464]383  /** Wait for threads in tree
[1409]384        type 0 - tree looks empty - see if any nodes outstanding
385             1 - tree not empty
386         2 - finish and do statistics
387        returns non-zero if keep going
388    */
[2464]389  int waitForThreadsInTree(int type);
[1409]390
[2464]391  /** Wait for threads n parallel cuts
[1409]392        type 0 - parallel cuts
393         1 - finishing parallel cuts
394    */
[2464]395  void waitForThreadsInCuts(int type, OsiCuts *eachCuts, int whichGenerator);
[1409]396
[2464]397  /// Split model and do work in deterministic parallel
398  void deterministicParallel();
399  /**
[1409]400       Locks a thread if parallel so that stuff like cut pool
401       can be updated and/or used.
402    */
[2464]403  inline void lockThread()
404  {
405    children_[numberThreads_].lockThread();
406  }
407  /**
[1409]408       Unlocks a thread if parallel to say cut pool stuff not needed
409    */
[2464]410  inline void unlockThread()
411  {
412    children_[numberThreads_].unlockThread();
413  }
[1409]414
[2464]415  /// Returns true if locked
416  inline bool isLocked() const
417  {
418    return children_[numberThreads_].locked();
419  }
[1409]420
[2464]421  /// Returns pointer to master thread
422  CbcThread *masterThread() const;
[1409]423
[2464]424  /// Returns pointer to a thread model
425  inline CbcModel *model(int i) const
426  {
427    return threadModel_[i];
428  }
[1409]429
[2464]430  /// Returns pointer to a child thread
431  inline CbcThread *child(int thread) const
432  {
433    return children_ + thread;
434  }
[2022]435
[2464]436  /// Returns number of children
437  inline int numberThreads() const
438  {
439    return numberThreads_;
440  }
[1409]441
[2464]442  /// Sets Dantzig state in children
443  void setDantzigState();
444
[1409]445private:
[2464]446  /// Number of children
447  int numberThreads_;
448  /// Child models (with base model at end)
449  CbcThread *children_;
450  /** type -1 cuts
[1409]451              0 opportunistic
452              1 deterministic */
[2464]453  int type_;
454  int *threadCount_;
455  CbcModel **threadModel_;
456  int numberObjects_;
457  OsiObject **saveObjects_;
458  int threadStats_[6];
459  int defaultParallelIterations_;
460  int defaultParallelNodes_;
[1409]461};
462#else
463// Dummy threads
464/** A class to encapsulate thread stuff */
465
466class CbcThread {
467public:
[2464]468  // Default Constructor
469  CbcThread() {}
[1409]470
[2464]471  virtual ~CbcThread() {}
[1409]472};
473/** Base model */
474
475class CbcBaseModel {
476public:
[2464]477  // Default Constructor (not declared here so that CbcThread.cpp not empty)
478  CbcBaseModel();
[1409]479
[2464]480  virtual ~CbcBaseModel() {}
[1409]481};
[1404]482#endif
[1409]483
484#endif
[2465]485
486/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
487*/
Note: See TracBrowser for help on using the repository browser.