source: trunk/Cbc/src/CbcThread.hpp @ 1514

Last change on this file since 1514 was 1432, checked in by bjarni, 10 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.