Ignore:
Timestamp:
Jan 5, 2010 11:20:52 AM (10 years ago)
Author:
forrest
Message:

try and modularize threads

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/sandbox/Cbc/src/CbcThread.hpp

    r1409 r1412  
    1010class OsiCuts;
    1111#ifdef CBC_THREAD
    12 // Threads
     12class CbcThread;
     13// Use pthreads
     14#define CBC_PTHREAD
     15#ifdef CBC_PTHREAD
    1316#include <pthread.h>
    1417typedef struct {
     
    1619    long                status;
    1720} Coin_pthread_t;
    18 
    19 #ifdef HAVE_CLOCK_GETTIME
    20 inline int my_gettime(struct timespec* tp)
    21 {
    22     return clock_gettime(CLOCK_REALTIME, tp);
    23 }
    24 #else
    25 #ifndef _MSC_VER
    26 inline int my_gettime(struct timespec* tp)
    27 {
    28     struct timeval tv;
    29     int ret = gettimeofday(&tv, NULL);
    30     tp->tv_sec = tv.tv_sec;
    31     tp->tv_nsec = tv.tv_usec * 1000;
    32     return ret;
    33 }
    34 #else
    35 inline int my_gettime(struct timespec* tp)
    36 {
    37     double t = CoinGetTimeOfDay();
    38     tp->tv_sec = (int)floor(t);
    39     tp->tv_nsec = (int)((tp->tv_sec - floor(t)) / 1000000.0);
    40     return 0;
    41 }
    4221#endif
    43 #endif
    44 /** A class to encapsulate phread stuff */
    45 
    46 
    47 class CbcPthread {
     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 {
    4832public:
    4933    // Default Constructor
    50     CbcPthread ();
    51 
    52     // Constructor with base model
    53     CbcPthread (CbcModel & model, int deterministic, CbcModel * baseModel);
    54 
    55     // Copy constructor
    56     CbcPthread ( const CbcPthread &);
    57 
    58     virtual ~CbcPthread();
    59 
    60     /// Assignment operator
    61     CbcPthread & operator=(const CbcPthread& rhs);
     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);
    6244    /**
    6345       Locks a thread if parallel so that stuff like cut pool
     
    6951    */
    7052    void unlockThread();
    71 
    72     /// Returns true if locked
    73     inline bool isLocked() const {
    74         return locked_;
    75     }
    76 
    77 public:
    78     CbcPthread * basePointer_; // for getting main mutex and threadid of base
    79     pthread_mutex_t mutex_; // for waking up threads
    80     pthread_cond_t condition_; // for waking up thread
     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
    8180    Coin_pthread_t threadId_;
    82     bool locked_;
     81#endif
     82    bool locked_; // For mutex2
    8383};
    84 
    8584/** A class to encapsulate thread stuff */
    8685
     
    9594    CbcThread ();
    9695
    97     // Constructor with base model
    98     CbcThread (CbcModel & model, int deterministic, CbcModel * baseModel);
    99 
    100     // Copy constructor
    101     CbcThread ( const CbcThread &);
    102 
    10396    virtual ~CbcThread();
    10497
    105     /// Assignment operator
    106     CbcThread & operator=(const CbcThread& rhs);
     98    /// Fills in useful stuff
     99    void setUsefulStuff (CbcModel * model, int deterministic,
     100                         CbcModel * baseModel,
     101                         CbcThread * master,
     102                         void *& masterMutex);
    107103    /**
    108104       Locks a thread if parallel so that stuff like cut pool
     
    119115        return locked_;
    120116    }
    121 
    122 public:
     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_;
    123292    CbcModel * baseModel_;
    124293    CbcModel * thisModel_;
    125294    CbcNode * node_; // filled in every time
    126295    CbcNode * createdNode_; // filled in every time on return
    127     Coin_pthread_t threadIdOfBase_;
    128     pthread_mutex_t * mutex_; // for locking data
    129     pthread_mutex_t * mutex2_; // for waking up threads
    130296    CbcThread * master_; // points back to master thread
    131     pthread_cond_t * condition2_; // for waking up thread
    132297    int returnCode_; // -1 available, 0 busy, 1 finished , 2??
    133298    double timeLocked_;
     
    135300    double timeWaitingToStart_;
    136301    double timeInThread_;
     302    double timeWhenLocked_; // time when thread got lock (in seconds)
    137303    int numberTimesLocked_;
    138304    int numberTimesUnlocked_;
     
    140306    int saveStuff_[2];
    141307    int dantzigState_; // 0 unset, -1 waiting to be set, 1 set
    142     struct timespec absTime_;
    143308    bool locked_;
    144309    int nDeleteNode_;
     
    148313    int iterationsThisTime_;
    149314    int deterministic_;
     315#ifdef THREAD_DEBUG
     316public:
     317    int threadNumber_;
     318    int lockCount_;
     319#endif
    150320};
    151321/** Base model */
     
    161331              0 opportunistic
    162332              1 deterministic */
    163     // CbcBaseModel (CbcModel & model, int numberThreads,
    164     //  void *(* function) (void *),
    165     //  int type);
    166333    /** Constructor with model
    167334        type -1 cuts
     
    170337    CbcBaseModel (CbcModel & model, int type);
    171338
    172     // Copy constructor
    173     CbcBaseModel ( const CbcBaseModel &);
    174 
    175339    virtual ~CbcBaseModel();
    176340
    177     /// Assignment operator
    178     CbcBaseModel & operator=(const CbcBaseModel& rhs);
    179 
    180     /// Stop all threads
    181     void stopThreads();
     341    /** Stop all threads
     342        -1 just check all in good state
     343        0 actually stop
     344    */
     345    void stopThreads(int type);
    182346
    183347    /** Wait for threads in tree
     
    213377    /// Returns true if locked
    214378    inline bool isLocked() const {
    215         return children_[numberThreads_].locked_;
     379        return children_[numberThreads_].locked();
    216380    }
    217381
    218382    /// Returns pointer to master thread
    219     inline CbcThread * masterThread() const {
    220         return children_ + numberThreads_;
    221     }
     383    CbcThread * masterThread() const;
    222384
    223385    /// Returns pointer to a thread model
     
    239401              1 deterministic */
    240402    int type_;
    241     pthread_mutex_t mutex_main_;
    242     pthread_cond_t condition_main_;
    243     pthread_mutex_t condition_mutex_;
    244     Coin_pthread_t * threadId_;
    245403    int * threadCount_;
    246404    CbcModel ** threadModel_;
    247     pthread_mutex_t * mutex2_;
    248     pthread_cond_t * condition2_;
    249405    int numberObjects_;
    250406    OsiObject ** saveObjects_;
     
    253409    int defaultParallelNodes_;
    254410};
    255 
    256 /** Simple general method - just passed n bundles of data and a function */
    257 
    258 
    259 class CbcSimpleThread {
    260 public:
    261     // Default Constructor
    262     CbcSimpleThread ();
    263 
    264     // Constructor with stuff
    265     CbcSimpleThread (int numberThreads,
    266                      void *(* function) (void *),
    267                      int sizeOfData,
    268                      void * data);
    269     // Constructor with stuff (type 0 -> doHeurThread)
    270     CbcSimpleThread (int numberThreads,
    271                      int type,
    272                      int sizeOfData,
    273                      void * data);
    274 
    275     virtual ~CbcSimpleThread();
    276 
    277 protected:
    278 
    279     /// Number of children
    280     int numberThreads_;
    281     /// data
    282     void * argBundle_;
    283 };
    284411#else
    285412// Dummy threads
Note: See TracChangeset for help on using the changeset viewer.