Line data Source code
1 : // -*- C++ -*- 2 : //# ThreadCoordinator.h: Definition of the ThreadCoordinator class 3 : //# Copyright (C) 1997,1998,1999,2000,2001,2002,2003 4 : //# Associated Universities, Inc. Washington DC, USA. 5 : //# 6 : //# This library is free software; you can redistribute it and/or modify it 7 : //# under the terms of the GNU Library General Public License as published by 8 : //# the Free Software Foundation; either version 2 of the License, or (at your 9 : //# option) any later version. 10 : //# 11 : //# This library is distributed in the hope that it will be useful, but WITHOUT 12 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 14 : //# License for more details. 15 : //# 16 : //# You should have received a copy of the GNU Library General Public License 17 : //# along with this library; if not, write to the Free Software Foundation, 18 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 19 : //# 20 : //# Correspondence concerning AIPS++ should be addressed as follows: 21 : //# Internet email: aips2-request@nrao.edu. 22 : //# Postal address: AIPS++ Project Office 23 : //# National Radio Astronomy Observatory 24 : //# 520 Edgemont Road 25 : //# Charlottesville, VA 22903-2475 USA 26 : //# 27 : //# $Id$ 28 : 29 : #include <casacore/casa/aips.h> 30 : #include <casacore/casa/aipstype.h> 31 : #include <cstddef> 32 : 33 : //<example> 34 : // 35 : // Code in the master thread: 36 : // 37 : // ThreadCoordinator threadCoordinator (nThreads); 38 : // 39 : // // Create nThread threads and pass them a pointer to the thread coordinator 40 : // // object. Then enter the work loop 41 : // 42 : // for (int i = 0; i < nBuffers; i++){ 43 : // 44 : // // Provide access to the i-th buffer 45 : // 46 : // threadCoordinator->getToWork(& vb); // tell workers to hop to it! 47 : // // blocks if workers still busy 48 : // 49 : // } 50 : // 51 : // Code in each worker thread: 52 : // 53 : // while (true){ 54 : // 55 : // VisBuffer * workingBuffer = threadCoordinator_p->waitForWork (this); 56 : // if (workingBuffer == NULL) 57 : // break; 58 : // 59 : // doSomeWork(workingBuffer); 60 : // } 61 : // </example> 62 : 63 : #ifndef SYNTHESIS_THREADCOORDINATOR_H 64 : #define SYNTHESIS_THREADCOORDINATOR_H 65 : 66 : namespace casacore{ 67 : 68 : class Mutex; 69 : class String; 70 : } 71 : 72 : namespace casa { 73 : 74 : class Barrier; 75 : 76 : namespace async { 77 : class Condition; 78 : class Mutex; 79 : class Thread; 80 : } 81 : 82 : class VisBuffer; 83 : 84 : class ThreadCoordinatorBase { 85 : 86 : public: 87 : 88 : virtual ~ThreadCoordinatorBase (); 89 : 90 : void waitForWorkersToFinishTask (); 91 : 92 : protected: 93 : 94 : ThreadCoordinatorBase (casacore::Int nThreads, bool logStates); 95 : 96 : 97 : void dispatchWork (); 98 : void getToWork (); 99 : virtual void installWorkInfo () = 0; 100 : bool waitForWork (const async::Thread * thisThread); 101 : void waitForWorkersToReport (); 102 : casacore::Int nThreads_p; 103 : 104 : 105 : private: 106 : 107 : Barrier * barrier_p; 108 : bool logStates_p; 109 : async::Mutex * mutex_p; 110 : volatile casacore::Int nThreadsAtBarrier_p; 111 : volatile casacore::Int nThreadsDispatched_p; 112 : volatile casacore::Bool readyForWork_p; 113 : async::Condition * stateChanged_p; 114 : //const VisBuffer * vb_p; 115 : volatile bool workCompleted_p; 116 : volatile bool workToBeDone_p; 117 : 118 : void logState (const casacore::String & tag) const; 119 : 120 : }; 121 : 122 : template <typename T> 123 : class ThreadCoordinator : public ThreadCoordinatorBase { 124 : 125 : public: 126 : 127 0 : ThreadCoordinator (casacore::Int nThreads, casacore::Bool logStates = false) : ThreadCoordinatorBase (nThreads, logStates) {} 128 : 129 : void 130 0 : giveWorkToWorkers (T * workInfo) 131 : { 132 0 : workInfoInWaiting_p = workInfo; 133 0 : waitForWorkersToReport (); 134 0 : dispatchWork (); 135 0 : } 136 : 137 : void 138 : getToWork (T * workInfo) 139 : { 140 : workInfoInWaiting_p = workInfo; 141 : ThreadCoordinatorBase::getToWork (); 142 : } 143 : 144 : T * 145 0 : waitForWork (const async::Thread * thisThread) 146 : { 147 0 : bool ok = ThreadCoordinatorBase::waitForWork (thisThread); 148 0 : T * result = ok ? workInfo_p : NULL; 149 : 150 0 : return result; 151 : } 152 : 153 0 : void setNThreads(casacore::Int n) {nThreads_p=n;}; 154 0 : casacore::Int nThreads() {return nThreads_p;}; 155 : protected: 156 : 157 : void 158 0 : installWorkInfo () 159 : { 160 0 : workInfo_p = workInfoInWaiting_p; 161 0 : workInfoInWaiting_p = NULL; 162 0 : } 163 : 164 : 165 : private: 166 : 167 : T * workInfoInWaiting_p; 168 : T * workInfo_p; 169 : }; 170 : 171 : } // end namespace casa 172 : 173 : #endif //