File: CbcThread.hpp

package info (click to toggle)
coinor-cbc 2.9.9+repack1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 7,848 kB
  • ctags: 5,787
  • sloc: cpp: 104,337; sh: 8,921; xml: 2,950; makefile: 520; ansic: 491; awk: 197
file content (448 lines) | stat: -rw-r--r-- 12,013 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
/* $Id: CbcThread.hpp 2022 2014-03-25 11:18:50Z forrest $ */
// Copyright (C) 2009, International Business Machines
// Corporation and others.  All Rights Reserved.
// This code is licensed under the terms of the Eclipse Public License (EPL).

#ifndef CbcThread_H
#define CbcThread_H

#include "CbcModel.hpp"
#include "CbcNode.hpp"
class OsiObject;
class OsiCuts;
#ifdef CBC_THREAD
class CbcThread;
// Use pthreads
#define CBC_PTHREAD
#ifdef CBC_PTHREAD
#include <pthread.h>
typedef struct {
    pthread_t	thr;
    long		status;
} Coin_pthread_t;
#endif
//#define THREAD_DEBUG 1
/** A class to encapsulate specific thread stuff
    To use another api with same style - you just need to implement
    these methods.

    At present just pthreads
 */


class CbcSpecificThread {
public:
    // Default Constructor
    CbcSpecificThread ();

    // Useful Constructor
    CbcSpecificThread (CbcSpecificThread * master, pthread_mutex_t * masterMutex);

    virtual ~CbcSpecificThread();

    // Useful stuff
    void setUsefulStuff (CbcSpecificThread * master,
                         void *& masterMutex);
    /**
       Locks a thread if parallel so that stuff like cut pool
       can be updated and/or used.
    */
    void lockThread();
    /**
       Unlocks a thread if parallel to say cut pool stuff not needed
    */
    void unlockThread();
    ///  Locks a thread for testing whether to start etc
    void lockThread2(bool doAnyway = false);
    ///  Unlocks a thread for testing whether to start etc
    void unlockThread2(bool doAnyway = false);
    /// Signal
    void signal();
    /// Timed wait in nanoseconds - if negative then seconds
    void timedWait(int time);
    /// Actually starts a thread
    void startThread(void * (*routine ) (void *), CbcThread * thread);
    /// Exits thread (called from master) - return code should be zero
    int exit();
    /// Exits thread
    void exitThread();
    /// Get status
    int status() const;
    /// Set status
    void setStatus(int value);
    //}


public: // private:
    CbcSpecificThread * basePointer_; // for getting main mutex and threadid of base
#ifdef CBC_PTHREAD
    pthread_mutex_t *masterMutex_; // for synchronizing
    pthread_mutex_t mutex2_; // for waking up threads
    pthread_cond_t condition2_; // for waking up thread
    Coin_pthread_t threadId_;
#endif
    bool locked_; // For mutex2
};
/** A class to encapsulate thread stuff */


class CbcThread {
private:
    void gutsOfDelete();
    void gutsOfCopy(const CbcThread & rhs);

public:
    // Default Constructor
    CbcThread ();

    virtual ~CbcThread();

    /// Fills in useful stuff
    void setUsefulStuff (CbcModel * model, int deterministic,
                         CbcModel * baseModel,
                         CbcThread * master,
                         void *& masterMutex);
    /**
       Locks a thread if parallel so that stuff like cut pool
       can be updated and/or used.
    */
    void lockThread();
    /**
       Unlocks a thread if parallel to say cut pool stuff not needed
    */
    void unlockThread();

    /// Returns true if locked
    inline bool isLocked() const {
        return locked_;
    }
    /** Wait for child to have return code NOT == to currentCode
        type - 0 timed wait
               1 wait
           returns true if return code changed */
    bool wait(int type, int currentCode);
    /// Just wait for so many nanoseconds
    void waitNano(int time);
    /// Signal child to carry on
    void signal();
    /// Lock from master with mutex2 and signal before lock
    void lockFromMaster();
    /// Unlock from master with mutex2 and signal after unlock
    void unlockFromMaster();
    /// Lock from thread with mutex2 and signal before lock
    void lockFromThread();
    /// Unlock from thread with mutex2 and signal after unlock
    void unlockFromThread();
    /// Exits thread (called from master) - return code should be zero
    int exit();
    /// Exits thread
    void exitThread();
    /// Waits until returnCode_ goes to zero
    void waitThread();
    /// Get status
    inline int status() const {
        return threadStuff_.status();
    }
    /// Set status
    inline void setStatus(int value) {
        threadStuff_.setStatus( value);
    }
    /// Get return code
    inline int returnCode() const {
        return returnCode_;
    }
    /// Set return code
    inline void setReturnCode(int value) {
        returnCode_ = value;
    }
    /// Get base model
    inline CbcModel * baseModel() const {
        return baseModel_;
    }
    /// Get this model
    inline CbcModel * thisModel() const {
        return thisModel_;
    }
    /// Get node
    inline CbcNode * node() const {
        return node_;
    }
    /// Set node
    inline void setNode(CbcNode * node) {
        node_ = node;
    }
    /// Get created node
    inline CbcNode * createdNode() const {
        return createdNode_;
    }
    /// Set created node
    inline void setCreatedNode(CbcNode * node) {
        createdNode_ = node;
    }
    /// Get dantzig state
    inline int dantzigState() const {
        return dantzigState_;
    }
    /// Set dantzig state
    inline void setDantzigState(int value) {
        dantzigState_ = value;
    }
    /// Get time in thread
    inline double timeInThread() const {
        return timeInThread_;
    }
    /// Increment time in thread
    inline void incrementTimeInThread(double value) {
        timeInThread_ += value;
    }
    /// Get time waiting to start
    inline double timeWaitingToStart() const {
        return timeWaitingToStart_;
    }
    /// Increment time waiting to start
    inline void incrementTimeWaitingToStart(double value) {
        timeWaitingToStart_ += value;
    }
    /// Get time locked
    inline double timeLocked() const {
        return timeLocked_;
    }
    /// Increment time locked
    inline void incrementTimeLocked(double value) {
        timeLocked_ += value;
    }
    /// Get time waiting to lock
    inline double timeWaitingToLock() const {
        return timeWaitingToLock_;
    }
    /// Increment time waiting to lock
    inline void incrementTimeWaitingToLock(double value) {
        timeWaitingToLock_ += value;
    }
    /// Get if deterministic
    inline int deterministic() const {
        return deterministic_;
    }
    /// Get maxDeleteNode
    inline int maxDeleteNode() const {
        return maxDeleteNode_;
    }
    /// Set maxDeleteNode
    inline void setMaxDeleteNode(int value) {
        maxDeleteNode_ = value;
    }
    /// Get nDeleteNode (may be fake i.e. defaultParallelIterations_)
    inline int nDeleteNode() const {
        return nDeleteNode_;
    }
    /// Set nDeleteNode (may be fake i.e. defaultParallelIterations_)
    inline void setNDeleteNode(int value) {
        nDeleteNode_ = value;
    }
    /// Clear delNode
    inline void clearDelNode() {
        delete delNode_;
        delNode_ = NULL;
    }
    /// Set fake delNode to pass across OsiCuts
    inline void fakeDelNode(CbcNode ** delNode) {
        delNode_ = delNode;
    }
    /// Get delNode
    inline CbcNode ** delNode() const {
        return delNode_;
    }
    /// Set delNode
    inline void setDelNode(CbcNode ** delNode) {
        delNode_ = delNode;
    }
    /// Get number times locked
    inline int numberTimesLocked() const {
        return numberTimesLocked_;
    }
    /// Get number times unlocked
    inline int numberTimesUnlocked() const {
        return numberTimesUnlocked_;
    }
    /// Get number of nodes this time
    inline int nodesThisTime() const {
        return nodesThisTime_;
    }
    /// Set number of nodes this time
    inline void setNodesThisTime(int value) {
        nodesThisTime_ = value;
    }
    /// Get number of iterations this time
    inline int iterationsThisTime() const {
        return iterationsThisTime_;
    }
    /// Set number of iterations this time
    inline void setIterationsThisTime(int value) {
        iterationsThisTime_ = value;
    }
    /// Get save stuff array
    inline int * saveStuff() {
        return saveStuff_;
    }
    /// Say if locked
    inline bool locked() const {
        return locked_;
    }

public: // private:
    CbcSpecificThread threadStuff_;
    CbcModel * baseModel_;
    CbcModel * thisModel_;
    CbcNode * node_; // filled in every time
    CbcNode * createdNode_; // filled in every time on return
    CbcThread * master_; // points back to master thread
    int returnCode_; // -1 available, 0 busy, 1 finished , 2??
    double timeLocked_;
    double timeWaitingToLock_;
    double timeWaitingToStart_;
    double timeInThread_;
    double timeWhenLocked_; // time when thread got lock (in seconds)
    int numberTimesLocked_;
    int numberTimesUnlocked_;
    int numberTimesWaitingToStart_;
    int saveStuff_[2];
    int dantzigState_; // 0 unset, -1 waiting to be set, 1 set
    bool locked_;
    int nDeleteNode_;
    CbcNode ** delNode_;
    int maxDeleteNode_;
    int nodesThisTime_;
    int iterationsThisTime_;
    int deterministic_;
#ifdef THREAD_DEBUG
public:
    int threadNumber_;
    int lockCount_;
#endif
};
/** Base model */


class CbcBaseModel {
public:
    // Default Constructor
    CbcBaseModel ();

    /** Constructor with model
        type -1 cuts
              0 opportunistic
              1 deterministic */
    /** Constructor with model
        type -1 cuts
              0 opportunistic
              1 deterministic */
    CbcBaseModel (CbcModel & model, int type);

    virtual ~CbcBaseModel();

    /** Stop all threads
        -1 just check all in good state
        0 actually stop
    */
    void stopThreads(int type);

    /** Wait for threads in tree
        type 0 - tree looks empty - see if any nodes outstanding
             1 - tree not empty
         2 - finish and do statistics
        returns non-zero if keep going
    */
    int waitForThreadsInTree(int type);

    /** Wait for threads n parallel cuts
        type 0 - parallel cuts
         1 - finishing parallel cuts
    */
    void waitForThreadsInCuts(int type, OsiCuts * eachCuts, int whichGenerator);

    /// Split model and do work in deterministic parallel
    void  deterministicParallel();
    /**
       Locks a thread if parallel so that stuff like cut pool
       can be updated and/or used.
    */
    inline void lockThread() {
        children_[numberThreads_].lockThread();
    }
    /**
       Unlocks a thread if parallel to say cut pool stuff not needed
    */
    inline void unlockThread() {
        children_[numberThreads_].unlockThread();
    }

    /// Returns true if locked
    inline bool isLocked() const {
        return children_[numberThreads_].locked();
    }

    /// Returns pointer to master thread
    CbcThread * masterThread() const;

    /// Returns pointer to a thread model
    inline CbcModel * model(int i) const {
        return threadModel_[i];
    }
  
    /// Returns pointer to a child thread
    inline CbcThread * child(int thread) const
    { return children_+thread;}

    /// Returns number of children
    inline int numberThreads() const
    { return numberThreads_;}

    /// Sets Dantzig state in children
    void setDantzigState();

private:

    /// Number of children
    int numberThreads_;
    /// Child models (with base model at end)
    CbcThread * children_;
    /** type -1 cuts
              0 opportunistic
              1 deterministic */
    int type_;
    int * threadCount_;
    CbcModel ** threadModel_;
    int numberObjects_;
    OsiObject ** saveObjects_;
    int threadStats_[6];
    int defaultParallelIterations_;
    int defaultParallelNodes_;
};
#else
// Dummy threads
/** A class to encapsulate thread stuff */


class CbcThread {
public:
    // Default Constructor
    CbcThread () {}

    virtual ~CbcThread() {}

};
/** Base model */


class CbcBaseModel {
public:
    // Default Constructor (not declared here so that CbcThread.cpp not empty)
    CbcBaseModel ();

    virtual ~CbcBaseModel() {}

};
#endif

#endif