source: stable/2.6/Cbc/src/CbcThread.hpp @ 2122

Last change on this file since 2122 was 1432, checked in by bjarni, 9 years ago

Added extra return at end of each source file where needed, to remove possible linefeed conflicts (NightlyBuild? errors)

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