source: stable/2.8/Cbc/src/CbcThread.hpp @ 2023

Last change on this file since 2023 was 2023, checked in by forrest, 5 years ago

fix thread bug

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