source: trunk/Cbc/src/CbcThread.hpp

Last change on this file was 2465, checked in by unxusr, 5 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
Line 
1/* $Id: CbcThread.hpp 2465 2019-01-03 19:26:52Z forrest $ */
2// Copyright (C) 2009, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#ifndef CbcThread_H
7#define CbcThread_H
8
9#include "CbcModel.hpp"
10#include "CbcNode.hpp"
11class OsiObject;
12class OsiCuts;
13#ifdef CBC_THREAD
14class CbcThread;
15// Use pthreads
16#define CBC_PTHREAD
17#ifdef CBC_PTHREAD
18#include <pthread.h>
19typedef struct {
20  pthread_t thr;
21  long status;
22} Coin_pthread_t;
23#endif
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.
28
29    At present just pthreads
30 */
31
32class CbcSpecificThread {
33public:
34  // Default Constructor
35  CbcSpecificThread();
36
37  // Useful Constructor
38  CbcSpecificThread(CbcSpecificThread *master, pthread_mutex_t *masterMutex);
39
40  virtual ~CbcSpecificThread();
41
42  // Useful stuff
43  void setUsefulStuff(CbcSpecificThread *master,
44    void *&masterMutex);
45  /**
46       Locks a thread if parallel so that stuff like cut pool
47       can be updated and/or used.
48    */
49  void lockThread();
50  /**
51       Unlocks a thread if parallel to say cut pool stuff not needed
52    */
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  //}
73
74public: // private:
75  CbcSpecificThread *basePointer_; // for getting main mutex and threadid of base
76#ifdef CBC_PTHREAD
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_;
81#endif
82  bool locked_; // For mutex2
83};
84/** A class to encapsulate thread stuff */
85
86class CbcThread {
87private:
88  void gutsOfDelete();
89  void gutsOfCopy(const CbcThread &rhs);
90
91public:
92  // Default Constructor
93  CbcThread();
94
95  virtual ~CbcThread();
96
97  /// Fills in useful stuff
98  void setUsefulStuff(CbcModel *model, int deterministic,
99    CbcModel *baseModel,
100    CbcThread *master,
101    void *&masterMutex);
102  /**
103       Locks a thread if parallel so that stuff like cut pool
104       can be updated and/or used.
105    */
106  void lockThread();
107  /**
108       Unlocks a thread if parallel to say cut pool stuff not needed
109    */
110  void unlockThread();
111
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
118        type - 0 timed wait
119               1 wait
120           returns true if return code changed */
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  }
326
327public: // private:
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_;
352#ifdef THREAD_DEBUG
353public:
354  int threadNumber_;
355  int lockCount_;
356#endif
357};
358/** Base model */
359
360class CbcBaseModel {
361public:
362  // Default Constructor
363  CbcBaseModel();
364
365  /** Constructor with model
366        type -1 cuts
367              0 opportunistic
368              1 deterministic */
369  /** Constructor with model
370        type -1 cuts
371              0 opportunistic
372              1 deterministic */
373  CbcBaseModel(CbcModel &model, int type);
374
375  virtual ~CbcBaseModel();
376
377  /** Stop all threads
378        -1 just check all in good state
379        0 actually stop
380    */
381  void stopThreads(int type);
382
383  /** Wait for threads in tree
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    */
389  int waitForThreadsInTree(int type);
390
391  /** Wait for threads n parallel cuts
392        type 0 - parallel cuts
393         1 - finishing parallel cuts
394    */
395  void waitForThreadsInCuts(int type, OsiCuts *eachCuts, int whichGenerator);
396
397  /// Split model and do work in deterministic parallel
398  void deterministicParallel();
399  /**
400       Locks a thread if parallel so that stuff like cut pool
401       can be updated and/or used.
402    */
403  inline void lockThread()
404  {
405    children_[numberThreads_].lockThread();
406  }
407  /**
408       Unlocks a thread if parallel to say cut pool stuff not needed
409    */
410  inline void unlockThread()
411  {
412    children_[numberThreads_].unlockThread();
413  }
414
415  /// Returns true if locked
416  inline bool isLocked() const
417  {
418    return children_[numberThreads_].locked();
419  }
420
421  /// Returns pointer to master thread
422  CbcThread *masterThread() const;
423
424  /// Returns pointer to a thread model
425  inline CbcModel *model(int i) const
426  {
427    return threadModel_[i];
428  }
429
430  /// Returns pointer to a child thread
431  inline CbcThread *child(int thread) const
432  {
433    return children_ + thread;
434  }
435
436  /// Returns number of children
437  inline int numberThreads() const
438  {
439    return numberThreads_;
440  }
441
442  /// Sets Dantzig state in children
443  void setDantzigState();
444
445private:
446  /// Number of children
447  int numberThreads_;
448  /// Child models (with base model at end)
449  CbcThread *children_;
450  /** type -1 cuts
451              0 opportunistic
452              1 deterministic */
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_;
461};
462#else
463// Dummy threads
464/** A class to encapsulate thread stuff */
465
466class CbcThread {
467public:
468  // Default Constructor
469  CbcThread() {}
470
471  virtual ~CbcThread() {}
472};
473/** Base model */
474
475class CbcBaseModel {
476public:
477  // Default Constructor (not declared here so that CbcThread.cpp not empty)
478  CbcBaseModel();
479
480  virtual ~CbcBaseModel() {}
481};
482#endif
483
484#endif
485
486/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
487*/
Note: See TracBrowser for help on using the repository browser.