Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/run/src/G4MTRunManager.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /run/src/G4MTRunManager.cc (Version 11.3.0) and /run/src/G4MTRunManager.cc (Version 10.4)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4MTRunManager implementation               << 
 27 //                                                 26 //
 28 // Original authors: X.Dong, A.Dotti - Februar << 
 29 // ------------------------------------------- << 
 30                                                    27 
 31 #include "G4MTRunManager.hh"                       28 #include "G4MTRunManager.hh"
 32                                                << 
 33 #include "G4AutoLock.hh"                       << 
 34 #include "G4CopyRandomState.hh"                << 
 35 #include "G4MTRunManagerKernel.hh"                 29 #include "G4MTRunManagerKernel.hh"
 36 #include "G4ProductionCutsTable.hh"            << 
 37 #include "G4Run.hh"                            << 
 38 #include "G4ScoringManager.hh"                 << 
 39 #include "G4StateManager.hh"                   << 
 40 #include "G4Timer.hh"                              30 #include "G4Timer.hh"
                                                   >>  31 #include "G4StateManager.hh"
                                                   >>  32 #include "G4ScoringManager.hh"
 41 #include "G4TransportationManager.hh"              33 #include "G4TransportationManager.hh"
 42 #include "G4UImanager.hh"                      <<  34 #include "G4VUserActionInitialization.hh"
 43 #include "G4UserRunAction.hh"                  << 
 44 #include "G4UserWorkerInitialization.hh"           35 #include "G4UserWorkerInitialization.hh"
 45 #include "G4UserWorkerThreadInitialization.hh"     36 #include "G4UserWorkerThreadInitialization.hh"
 46 #include "G4VUserActionInitialization.hh"      << 
 47 #include "G4WorkerRunManager.hh"               << 
 48 #include "G4WorkerThread.hh"                       37 #include "G4WorkerThread.hh"
                                                   >>  38 #include "G4Run.hh"
                                                   >>  39 #include "G4UImanager.hh"
                                                   >>  40 #include "G4AutoLock.hh"
                                                   >>  41 #include "G4WorkerRunManager.hh"
                                                   >>  42 #include "G4UserRunAction.hh"
                                                   >>  43 #include "G4ProductionCutsTable.hh"
                                                   >>  44 #include "G4Timer.hh"
 49                                                    45 
 50 G4ScoringManager* G4MTRunManager::masterScM =  <<  46 G4ScoringManager* G4MTRunManager::masterScM = 0;
 51 G4MTRunManager* G4MTRunManager::fMasterRM = nu <<  47 G4MTRunManager::masterWorlds_t G4MTRunManager::masterWorlds = G4MTRunManager::masterWorlds_t();
                                                   >>  48 G4MTRunManager* G4MTRunManager::fMasterRM = 0;
 52 G4int G4MTRunManager::seedOncePerCommunication     49 G4int G4MTRunManager::seedOncePerCommunication = 0;
 53 G4ThreadId G4MTRunManager::masterThreadId = G4 << 
 54                                                    50 
 55 // ------------------------------------------- <<  51 namespace {
 56 namespace                                      <<  52  G4Mutex cmdHandlingMutex = G4MUTEX_INITIALIZER;
 57 {                                              <<  53  G4Mutex scorerMergerMutex = G4MUTEX_INITIALIZER;
 58 G4Mutex cmdHandlingMutex = G4MUTEX_INITIALIZER <<  54  G4Mutex runMergerMutex = G4MUTEX_INITIALIZER;
 59 G4Mutex scorerMergerMutex = G4MUTEX_INITIALIZE <<  55  G4Mutex setUpEventMutex = G4MUTEX_INITIALIZER;
 60 G4Mutex runMergerMutex = G4MUTEX_INITIALIZER;  <<  56 }
 61 G4Mutex setUpEventMutex = G4MUTEX_INITIALIZER; << 
 62 }  // namespace                                << 
 63                                                    57 
 64 // ------------------------------------------- << 
 65 G4MTRunManager* G4MTRunManager::GetMasterRunMa     58 G4MTRunManager* G4MTRunManager::GetMasterRunManager()
 66 {                                                  59 {
 67   return fMasterRM;                            <<  60 ////////#ifdef G4MULTITHREADED
                                                   >>  61     return fMasterRM;
                                                   >>  62 ////////#else
                                                   >>  63 ////////    return G4RunManager::GetRunManager();
                                                   >>  64 ////////#endif
 68 }                                                  65 }
 69                                                    66 
 70 // ------------------------------------------- << 
 71 G4RunManagerKernel* G4MTRunManager::GetMasterR     67 G4RunManagerKernel* G4MTRunManager::GetMasterRunManagerKernel()
 72 {                                                  68 {
 73   return fMasterRM->kernel;                    <<  69     return fMasterRM->kernel;
 74 }                                                  70 }
 75                                                    71 
 76 // ------------------------------------------- << 
 77 G4MTRunManagerKernel* G4MTRunManager::GetMTMas     72 G4MTRunManagerKernel* G4MTRunManager::GetMTMasterRunManagerKernel()
 78 {                                                  73 {
 79   return fMasterRM->MTkernel;                  <<  74     return fMasterRM->MTkernel;
 80 }                                              << 
 81                                                << 
 82 // ------------------------------------------- << 
 83 G4ScoringManager* G4MTRunManager::GetMasterSco << 
 84 {                                              << 
 85   return masterScM;                            << 
 86 }                                              << 
 87                                                << 
 88 // ------------------------------------------- << 
 89 G4MTRunManager::masterWorlds_t& G4MTRunManager << 
 90 {                                              << 
 91   static masterWorlds_t masterWorlds;          << 
 92   return masterWorlds;                         << 
 93 }                                              << 
 94                                                << 
 95 // ------------------------------------------- << 
 96 void G4MTRunManager::addWorld(G4int counter, G << 
 97 {                                              << 
 98   GetMasterWorlds().insert(std::make_pair(coun << 
 99 }                                              << 
100                                                << 
101 // ------------------------------------------- << 
102 G4ThreadId G4MTRunManager::GetMasterThreadId() << 
103 {                                              << 
104   return masterThreadId;                       << 
105 }                                              << 
106                                                << 
107 // ------------------------------------------- << 
108 G4int G4MTRunManager::SeedOncePerCommunication << 
109 {                                              << 
110   return seedOncePerCommunication;             << 
111 }                                              << 
112                                                << 
113 // ------------------------------------------- << 
114 void G4MTRunManager::SetSeedOncePerCommunicati << 
115 {                                              << 
116   seedOncePerCommunication = val;              << 
117 }                                                  75 }
118                                                    76 
119 // ------------------------------------------- <<  77 G4MTRunManager::G4MTRunManager() : G4RunManager(masterRM),
120 G4MTRunManager::G4MTRunManager() : G4RunManage <<  78     nworkers(2),forcedNwokers(-1),pinAffinity(0),
121 {                                              <<  79     masterRNGEngine(0),
122   if (fMasterRM != nullptr) {                  <<  80     nextActionRequest(WorkerActionRequest::UNDEFINED),
123     G4Exception("G4MTRunManager::G4MTRunManage <<  81     eventModuloDef(0),eventModulo(1),
124                 "Another instance of a G4MTRun <<  82     nSeedsUsed(0),nSeedsFilled(0),
125   }                                            <<  83     nSeedsMax(10000),nSeedsPerEvent(2)
126   fMasterRM = this;                            <<  84 {
127   masterThreadId = G4ThisThread::get_id();     <<  85     if ( fMasterRM )
128   MTkernel = static_cast<G4MTRunManagerKernel* <<  86     {
                                                   >>  87         G4Exception("G4MTRunManager::G4MTRunManager", "Run0110",FatalException,
                                                   >>  88                     "Another instance of a G4MTRunManager already exists.");
                                                   >>  89     }
                                                   >>  90     fMasterRM = this;
                                                   >>  91     MTkernel = static_cast<G4MTRunManagerKernel*>(kernel);
129 #ifndef G4MULTITHREADED                            92 #ifndef G4MULTITHREADED
130   G4ExceptionDescription msg;                  <<  93     G4ExceptionDescription msg;
131   msg << "Geant4 code is compiled without mult <<  94     msg << "Geant4 code is compiled without multi-threading support"
132       << "(-DG4MULTITHREADED is set to off).\n <<  95         << "(-DG4MULTITHREADED is set to off).\n";
133   msg << "G4MTRunManager can only be used in m <<  96     msg << "G4MTRunManager can only be used in multi-threaded applications.";
134   G4Exception("G4MTRunManager::G4MTRunManager" <<  97     G4Exception("G4MTRunManager::G4MTRunManager","Run0111",FatalException,msg);
135 #endif                                             98 #endif
136                                                    99 
137   G4int numberOfStaticAllocators = kernel->Get << 100     G4int numberOfStaticAllocators = kernel->GetNumberOfStaticAllocators();
138   if (numberOfStaticAllocators > 0) {          << 101     if(numberOfStaticAllocators>0)
139     G4ExceptionDescription msg1;               << 102     {
140     msg1 << "There are " << numberOfStaticAllo << 103       G4ExceptionDescription msg1;
141          << "In multi-threaded mode, all G4All << 104       msg1 << "There are " << numberOfStaticAllocators
142             "instantiated.";                   << 105            << " static G4Allocator objects detected.\n"
143     G4Exception("G4MTRunManager::G4MTRunManage << 106            << "In multi-threaded mode, all G4Allocator objects must be dynamicly instantiated.";
144   }                                            << 107       G4Exception("G4MTRunManager::G4MTRunManager","Run1035",FatalException,msg1);
145   G4UImanager::GetUIpointer()->SetMasterUIMana << 108     }
146   masterScM = G4ScoringManager::GetScoringMana << 109     G4UImanager::GetUIpointer()->SetMasterUIManager(true);
147                                                << 110     masterScM = G4ScoringManager::GetScoringManagerIfExist();
148   // Check if a default RandomNumberGenerator  << 111 
149   // if not create default one                 << 112     //Check if a default RandomNumberGenerator has been created by user,
150   // Note this call forces creation of default << 113     // if not create default one
151   // G4Random::getTheEngine(); //User did not  << 114     //Note this call forces creation of defaults if not already there
152   // Now remember the master instance of the R << 115     //G4Random::getTheEngine(); //User did not specify RNG, create defaults
153   masterRNGEngine = G4Random::getTheEngine();  << 116     //Now remember the master instance of the RNG Engine
154                                                << 117     masterRNGEngine = G4Random::getTheEngine();
155   randDbl = new G4double[nSeedsPerEvent * nSee << 118 
156                                                << 119     numberOfEventToBeProcessed = 0;
157   char* env = std::getenv("G4FORCENUMBEROFTHRE << 120     randDbl = new double[nSeedsPerEvent*nSeedsMax];
158   if (env != nullptr) {                        << 121 
159     G4String envS = env;                       << 122     char* env = getenv("G4FORCENUMBEROFTHREADS");
160     if (envS == "MAX" || envS == "max") {      << 123     if(env)
161       forcedNwokers = G4Threading::G4GetNumber << 124     {
162     }                                          << 125       G4String envS = env;
163     else {                                     << 126       if(envS=="MAX"||envS=="max")
164       std::istringstream is(env);              << 127       { forcedNwokers = G4Threading::G4GetNumberOfCores(); }
165       G4int val = -1;                          << 128       else
166       is >> val;                               << 129       {
167       if (val > 0) {                           << 130         std::istringstream is(env);
168         forcedNwokers = val;                   << 131         G4int val = -1;
                                                   >> 132         is >> val;
                                                   >> 133         if(val>0)
                                                   >> 134         { forcedNwokers = val; }
                                                   >> 135         else
                                                   >> 136         {
                                                   >> 137           G4ExceptionDescription msg2;
                                                   >> 138           msg2 << "Environment variable G4FORCENUMBEROFTHREADS has an invalid value <"
                                                   >> 139                << envS << ">. It has to be an integer or a word \"max\".\n"
                                                   >> 140                << "G4FORCENUMBEROFTHREADS is ignored.";
                                                   >> 141           G4Exception("G4MTRunManager::G4MTRunManager","Run1039",JustWarning,msg2);
                                                   >> 142         }
169       }                                           143       }
170       else {                                   << 144       if(forcedNwokers>0)
171         G4ExceptionDescription msg2;           << 145       {
172         msg2 << "Environment variable G4FORCEN << 146         nworkers = forcedNwokers;
173                 "value <"                      << 147         G4cout << "### Number of threads is forced to " << forcedNwokers 
174              << envS << ">. It has to be an in << 
175              << "G4FORCENUMBEROFTHREADS is ign << 
176         G4Exception("G4MTRunManager::G4MTRunMa << 
177       }                                        << 
178     }                                          << 
179     if (forcedNwokers > 0) {                   << 
180       nworkers = forcedNwokers;                << 
181       if (verboseLevel > 0) {                  << 
182         G4cout << "### Number of threads is fo << 
183                << " by Environment variable G4    148                << " by Environment variable G4FORCENUMBEROFTHREADS." << G4endl;
184       }                                           149       }
185     }                                             150     }
186   }                                            << 
187   G4UImanager::GetUIpointer()->SetAlias("RunMo << 
188 }                                                 151 }
189                                                   152 
190 // ------------------------------------------- << 
191 G4MTRunManager::~G4MTRunManager()                 153 G4MTRunManager::~G4MTRunManager()
192 {                                                 154 {
193   // TODO: Currently does not work due to conc << 155     //TODO: Currently does not work due to concurrent deletion of something
194   //      that is shared:                      << 156     //      that is shared:
195   // G4ProcessTable::DeleteMessenger from ~G4R << 157     //G4ProcessTable::DeleteMessenger from ~G4RunManager
196   // G4cout<<"Destroy MTRunManager"<<G4endl;// << 158     //G4cout<<"Destroy MTRunManager"<<G4endl;//ANDREA
197   TerminateWorkers();                          << 159     TerminateWorkers();
198   delete[] randDbl;                            << 160     delete [] randDbl;
199 }                                              << 161 }
200                                                << 162 
201 // ------------------------------------------- << 163 void G4MTRunManager::StoreRNGStatus(const G4String& fn )
202 void G4MTRunManager::StoreRNGStatus(const G4St << 164 {
203 {                                              << 165     std::ostringstream os;
204   std::ostringstream os;                       << 166     os << randomNumberStatusDir << "G4Master_"<<fn <<".rndm";
205   os << randomNumberStatusDir << "G4Master_" < << 167     G4Random::saveEngineStatus(os.str().c_str());
206   G4Random::saveEngineStatus(os.str().c_str()) << 168 }
207 }                                              << 169 
208                                                << 170 void G4MTRunManager::SetNumberOfThreads(G4int n )
209 // ------------------------------------------- << 171 {
210 void G4MTRunManager::rndmSaveThisRun()         << 172     if ( threads.size() != 0 )
211 {                                              << 173     {
212   G4int runNumber = 0;                         << 174       G4ExceptionDescription msg;
213   if (currentRun != nullptr) runNumber = curre << 175       msg << "Number of threads cannot be changed at this moment \n"
214   if (!storeRandomNumberStatus) {              << 176           << "(old threads are still alive). Method ignored.";
215     G4cerr << "Warning from G4RunManager::rndm << 177       G4Exception("G4MTRunManager::SetNumberOfThreads(G4int)",
216            << " Random number status was not s << 178                   "Run0112", JustWarning, msg);
217            << "/random/setSavingFlag command m << 179     }
218            << "Command ignored." << G4endl;    << 180     else if ( forcedNwokers > 0 )
219     return;                                    << 181     {
220   }                                            << 182       G4ExceptionDescription msg;
221                                                << 183       msg << "Number of threads is forced to " << forcedNwokers
222   G4fs::path fileIn = randomNumberStatusDir +  << 184           << " by G4FORCENUMBEROFTHREADS shell variable.\n"
223                                                << 185           << "Method ignored.";
224   std::ostringstream os;                       << 186       G4Exception("G4MTRunManager::SetNumberOfThreads(G4int)",
225   os << "run" << runNumber << ".rndm" << '\0'; << 187                   "Run0113", JustWarning, msg);
226   G4fs::path fileOut = randomNumberStatusDir + << 188     }
227                                                << 189     else  
228   if (G4CopyRandomState(fileIn, fileOut, "G4MT << 190     {
229   {                                            << 191       nworkers = n;
230     G4cout << fileIn << " is copied to " << fi << 192     }
231   }                                            << 
232 }                                              << 
233                                                << 
234 // ------------------------------------------- << 
235 void G4MTRunManager::rndmSaveThisEvent()       << 
236 {                                              << 
237   G4Exception("G4MTRunManager::rndmSaveThisEve << 
238               "This method shall not be invoke << 
239 }                                              << 
240                                                << 
241 // ------------------------------------------- << 
242 void G4MTRunManager::SetNumberOfThreads(G4int  << 
243 {                                              << 
244   if (!threads.empty()) {                      << 
245     G4ExceptionDescription msg;                << 
246     msg << "Number of threads cannot be change << 
247         << "(old threads are still alive). Met << 
248     G4Exception("G4MTRunManager::SetNumberOfTh << 
249   }                                            << 
250   else if (forcedNwokers > 0) {                << 
251     G4ExceptionDescription msg;                << 
252     msg << "Number of threads is forced to " < << 
253         << " by G4FORCENUMBEROFTHREADS shell v << 
254         << "Method ignored.";                  << 
255     G4Exception("G4MTRunManager::SetNumberOfTh << 
256   }                                            << 
257   else {                                       << 
258     nworkers = n;                              << 
259   }                                            << 
260 }                                                 193 }
261                                                   194 
262 // ------------------------------------------- << 
263 void G4MTRunManager::Initialize()                 195 void G4MTRunManager::Initialize()
264 {                                                 196 {
265   G4RunManager::Initialize();                  << 197     G4RunManager::Initialize();
266                                                   198 
267   // make sure all worker threads are set up.  << 199     // make sure all worker threads are set up.
268   BeamOn(0);                                   << 200     BeamOn(0);
269   SetRunIDCounter(0);                          << 201     SetRunIDCounter(0);
                                                   >> 202     ///G4UImanager::GetUIpointer()->SetIgnoreCmdNotFound(true);
270 }                                                 203 }
271                                                   204 
272 // ------------------------------------------- << 205 ////void G4MTRunManager::TerminateEventLoop()
                                                   >> 206 ////{
                                                   >> 207 ////    //Nothing to do
                                                   >> 208 ////}
273 void G4MTRunManager::ProcessOneEvent(G4int)       209 void G4MTRunManager::ProcessOneEvent(G4int)
274 {                                                 210 {
275   // Nothing to do                             << 211     //Nothing to do
276 }                                                 212 }
277                                                << 
278 // ------------------------------------------- << 
279 void G4MTRunManager::TerminateOneEvent()          213 void G4MTRunManager::TerminateOneEvent()
280 {                                                 214 {
281   // Nothing to do                             << 215     //Nothing to do
282 }                                                 216 }
283                                                   217 
284 // ------------------------------------------- << 218 void G4MTRunManager::PrepareCommandsStack() {
285 void G4MTRunManager::PrepareCommandsStack()    << 219     G4AutoLock l(&cmdHandlingMutex);
286 {                                              << 220     uiCmdsForWorkers.clear();
287   G4AutoLock l(&cmdHandlingMutex);             << 221     std::vector<G4String>* cmdCopy = G4UImanager::GetUIpointer()->GetCommandStack();
288   uiCmdsForWorkers.clear();                    << 222     for ( std::vector<G4String>::const_iterator it = cmdCopy->begin() ;
289   std::vector<G4String>* cmdCopy = G4UImanager << 223          it != cmdCopy->end(); ++it )
290   for (const auto& it : *cmdCopy)              << 224         uiCmdsForWorkers.push_back(*it);
291     uiCmdsForWorkers.push_back(it);            << 225     cmdCopy->clear();
292   cmdCopy->clear();                            << 226     delete cmdCopy;
293   delete cmdCopy;                              << 
294 }                                                 227 }
295                                                   228 
296 // ------------------------------------------- << 
297 std::vector<G4String> G4MTRunManager::GetComma    229 std::vector<G4String> G4MTRunManager::GetCommandStack()
298 {                                                 230 {
299   G4AutoLock l(&cmdHandlingMutex);             << 231     G4AutoLock l(&cmdHandlingMutex);
300   return uiCmdsForWorkers;                     << 232     return uiCmdsForWorkers;
301 }                                                 233 }
302                                                   234 
303 // ------------------------------------------- << 
304 void G4MTRunManager::CreateAndStartWorkers()      235 void G4MTRunManager::CreateAndStartWorkers()
305 {                                                 236 {
306   // Now loop on requested number of workers   << 237     //Now loop on requested number of workers
307   // This will also start the workers          << 238     //This will also start the workers
308   // Currently we do not allow to change the   << 239     //Currently we do not allow to change the
309   // number of threads: threads area created o << 240     //number of threads: threads area created once
310   if (threads.empty()) {                       << 241     if ( threads.size() == 0 ) {
311     if (verboseLevel > 0) {                    << 242         for ( G4int nw = 0 ; nw<nworkers; ++nw) {
312       // for consistency with G4TaskRunManager << 243             //Create a new worker and remember it
313       std::stringstream msg;                   << 244             G4WorkerThread* context = new G4WorkerThread;
314       msg << "--> G4MTRunManager::CreateAndSta << 245             context->SetNumberThreads(nworkers);
315           << "Initializing workers...";        << 246             context->SetThreadId(nw);
316                                                << 247             G4Thread* thread = userWorkerThreadInitialization->CreateAndStartWorker(context);
317       std::stringstream ss;                    << 248             threads.push_back(thread);
318       ss.fill('=');                            << 249         }
319       ss << std::setw(G4int(msg.str().length() << 
320       G4cout << "\n" << ss.str() << "\n" << ms << 
321     }                                          << 
322                                                << 
323     for (G4int nw = 0; nw < nworkers; ++nw) {  << 
324       // Create a new worker and remember it   << 
325       auto context = new G4WorkerThread;       << 
326       context->SetNumberThreads(nworkers);     << 
327       context->SetThreadId(nw);                << 
328       G4Thread* thread = userWorkerThreadIniti << 
329       threads.push_back(thread);               << 
330     }                                             250     }
331   }                                            << 251     //Signal to threads they can start a new run
332   // Signal to threads they can start a new ru << 252     NewActionRequest(WorkerActionRequest::NEXTITERATION);
333   NewActionRequest(WorkerActionRequest::NEXTIT << 
334 }                                                 253 }
335                                                   254 
336 // ------------------------------------------- << 255 
337 void G4MTRunManager::InitializeEventLoop(G4int    256 void G4MTRunManager::InitializeEventLoop(G4int n_event, const char* macroFile, G4int n_select)
338 {                                                 257 {
339   MTkernel->SetUpDecayChannels();                 258   MTkernel->SetUpDecayChannels();
340   numberOfEventToBeProcessed = n_event;           259   numberOfEventToBeProcessed = n_event;
341   numberOfEventProcessed = 0;                     260   numberOfEventProcessed = 0;
342                                                   261 
343   if (!fakeRun) {                              << 262   if(!fakeRun)
                                                   >> 263   {
344     nSeedsUsed = 0;                               264     nSeedsUsed = 0;
345     nSeedsFilled = 0;                             265     nSeedsFilled = 0;
346                                                   266 
347     if (verboseLevel > 0) {                    << 267     if(verboseLevel>0)
348       timer->Start();                          << 268     { timer->Start(); }
349     }                                          << 269     
350                                                << 
351     n_select_msg = n_select;                      270     n_select_msg = n_select;
352     if (macroFile != nullptr) {                << 271     if(macroFile!=0)
353       if (n_select_msg < 0) n_select_msg = n_e << 272     {
354       msgText = "/control/execute ";           << 273         if(n_select_msg<0) n_select_msg = n_event;
355       msgText += macroFile;                    << 274         msgText = "/control/execute ";
356       selectMacro = macroFile;                 << 275         msgText += macroFile;
357     }                                          << 276         selectMacro = macroFile;
358     else {                                     << 277     }
359       n_select_msg = -1;                       << 278     else
360       selectMacro = "";                        << 279     {
361     }                                          << 280         n_select_msg = -1;
362                                                << 281         selectMacro = "";
363     // initialize seeds                        << 282     }
364     // If user did not implement InitializeSee << 283 
365     // use default: nSeedsPerEvent seeds per e << 284     //initialize seeds
366     if (eventModuloDef > 0) {                  << 285     //If user did not implement InitializeSeeds,
                                                   >> 286     // use default: nSeedsPerEvent seeds per event 
                                                   >> 287     if( eventModuloDef > 0 )
                                                   >> 288     {
367       eventModulo = eventModuloDef;               289       eventModulo = eventModuloDef;
368       if (eventModulo > numberOfEventToBeProce << 290       if(eventModulo > numberOfEventToBeProcessed/nworkers)
369         eventModulo = numberOfEventToBeProcess << 291       {
370         if (eventModulo < 1) eventModulo = 1;  << 292         eventModulo = numberOfEventToBeProcessed/nworkers;
                                                   >> 293         if(eventModulo<1) eventModulo =1;
371         G4ExceptionDescription msgd;              294         G4ExceptionDescription msgd;
372         msgd << "Event modulo is reduced to "     295         msgd << "Event modulo is reduced to " << eventModulo
373              << " to distribute events to all  << 296             << " to distribute events to all threads.";
374         G4Exception("G4MTRunManager::Initializ << 297         G4Exception("G4MTRunManager::InitializeEventLoop()",
                                                   >> 298                   "Run10035", JustWarning, msgd);
375       }                                           299       }
376     }                                             300     }
377     else {                                     << 301     else
378       eventModulo = G4int(std::sqrt(G4double(n << 302     {
379       if (eventModulo < 1) eventModulo = 1;    << 303       eventModulo = int(std::sqrt(double(numberOfEventToBeProcessed/nworkers)));
380     }                                          << 304       if(eventModulo<1) eventModulo =1;
381     if (!InitializeSeeds(n_event) && n_event > << 305     }
382       G4RNGHelper* helper = G4RNGHelper::GetIn << 306     if ( InitializeSeeds(n_event) == false && n_event>0 )
383       switch (seedOncePerCommunication) {      << 307     {
384         case 0:                                << 308         G4RNGHelper* helper = G4RNGHelper::GetInstance();
                                                   >> 309         switch(seedOncePerCommunication)
                                                   >> 310         {
                                                   >> 311          case 0:
385           nSeedsFilled = n_event;                 312           nSeedsFilled = n_event;
386           break;                                  313           break;
387         case 1:                                << 314          case 1:
388           nSeedsFilled = nworkers;                315           nSeedsFilled = nworkers;
389           break;                                  316           break;
390         case 2:                                << 317          case 2:
391           nSeedsFilled = n_event / eventModulo << 318           nSeedsFilled = n_event/eventModulo + 1;
392           break;                                  319           break;
393         default:                               << 320          default:
394           G4ExceptionDescription msgd;            321           G4ExceptionDescription msgd;
395           msgd << "Parameter value <" << seedO    322           msgd << "Parameter value <" << seedOncePerCommunication
396                << "> of seedOncePerCommunicati << 323                << "> of seedOncePerCommunication is invalid. It is reset to 0." ;
397           G4Exception("G4MTRunManager::Initial << 324           G4Exception("G4MTRunManager::InitializeEventLoop()",
                                                   >> 325                   "Run10036", JustWarning, msgd);
398           seedOncePerCommunication = 0;           326           seedOncePerCommunication = 0;
399           nSeedsFilled = n_event;                 327           nSeedsFilled = n_event;
400       }                                        << 328         }
401                                                   329 
402       // Generates up to nSeedsMax seed pairs  << 330         // Generates up to nSeedsMax seed pairs only.
403       if (nSeedsFilled > nSeedsMax) nSeedsFill << 331         if(nSeedsFilled>nSeedsMax) nSeedsFilled=nSeedsMax;
404       masterRNGEngine->flatArray(nSeedsPerEven << 332         masterRNGEngine->flatArray(nSeedsPerEvent*nSeedsFilled,randDbl); 
405       helper->Fill(randDbl, nSeedsFilled, n_ev << 333         helper->Fill(randDbl,nSeedsFilled,n_event,nSeedsPerEvent);
406     }                                             334     }
407   }                                               335   }
408                                                << 336   
409   // Now initialize workers. Check if user def << 337   //Now initialize workers. Check if user defined a WorkerThreadInitialization
410   if (userWorkerThreadInitialization == nullpt << 338   if ( userWorkerThreadInitialization == 0 )
411     userWorkerThreadInitialization = new G4Use << 339   { userWorkerThreadInitialization = new G4UserWorkerThreadInitialization(); }
412   }                                            << 340     
413                                                << 341   //Prepare UI commands for threads
414   // Prepare UI commands for threads           << 
415   PrepareCommandsStack();                         342   PrepareCommandsStack();
416                                                   343 
417   // Start worker threads                      << 344   //Start worker threads
418   CreateAndStartWorkers();                        345   CreateAndStartWorkers();
419                                                << 346     
420   // We need a barrier here. Wait for workers     347   // We need a barrier here. Wait for workers to start event loop.
421   // This will return only when all workers ha << 348   //This will return only when all workers have started processing events.
422   WaitForReadyWorkers();                          349   WaitForReadyWorkers();
423 }                                                 350 }
424                                                   351 
425 // ------------------------------------------- << 
426 void G4MTRunManager::RefillSeeds()                352 void G4MTRunManager::RefillSeeds()
427 {                                                 353 {
428   G4RNGHelper* helper = G4RNGHelper::GetInstan    354   G4RNGHelper* helper = G4RNGHelper::GetInstance();
429   G4int nFill = 0;                                355   G4int nFill = 0;
430   switch (seedOncePerCommunication) {          << 356   switch(seedOncePerCommunication)
431     case 0:                                    << 357   {
432       nFill = numberOfEventToBeProcessed - nSe << 358    case 0:
433       break;                                   << 359     nFill = numberOfEventToBeProcessed - nSeedsFilled;
434     case 1:                                    << 360     break;
435       nFill = nworkers - nSeedsFilled;         << 361    case 1:
436       break;                                   << 362     nFill = nworkers - nSeedsFilled;
437     case 2:                                    << 363     break;
438     default:                                   << 364    case 2:
439       nFill = (numberOfEventToBeProcessed - nS << 365    default:
                                                   >> 366     nFill = (numberOfEventToBeProcessed - nSeedsFilled*eventModulo)/eventModulo + 1;
440   }                                               367   }
441   // Generates up to nSeedsMax seed pairs only    368   // Generates up to nSeedsMax seed pairs only.
442   if (nFill > nSeedsMax) nFill = nSeedsMax;    << 369   if(nFill>nSeedsMax) nFill=nSeedsMax;
443   masterRNGEngine->flatArray(nSeedsPerEvent *  << 370   masterRNGEngine->flatArray(nSeedsPerEvent*nFill,randDbl); 
444   helper->Refill(randDbl, nFill);              << 371   helper->Refill(randDbl,nFill);
445   nSeedsFilled += nFill;                          372   nSeedsFilled += nFill;
                                                   >> 373 //G4cout<<"helper->Refill() for "<<nFill<<" events."<<G4endl;
446 }                                                 374 }
447                                                << 375     
448 // ------------------------------------------- << 
449 void G4MTRunManager::RunTermination()             376 void G4MTRunManager::RunTermination()
450 {                                                 377 {
451   // Wait for all worker threads to have finis << 378   //Wait for all worker threads to have finished the run
452   // i.e. wait for them to return from RunTerm << 379   //i.e. wait for them to return from RunTermination()
453   // This guarantee that userrunaction for wor << 380   //This guarantee that userrunaction for workers has been called
454                                                   381 
455   // Wait now for all threads to finish event-    382   // Wait now for all threads to finish event-loop
456   WaitForEndEventLoopWorkers();                   383   WaitForEndEventLoopWorkers();
457   // Now call base-class methof                << 384   //Now call base-class methof
458   G4RunManager::TerminateEventLoop();             385   G4RunManager::TerminateEventLoop();
459   G4RunManager::RunTermination();                 386   G4RunManager::RunTermination();
460 }                                                 387 }
461                                                   388 
462 // ------------------------------------------- << 
463 void G4MTRunManager::ConstructScoringWorlds()     389 void G4MTRunManager::ConstructScoringWorlds()
464 {                                                 390 {
465   masterScM = G4ScoringManager::GetScoringMana << 391     masterScM = G4ScoringManager::GetScoringManagerIfExist();
466   // Call base class stuff...                  << 392     //Call base class stuff...
467   G4RunManager::ConstructScoringWorlds();      << 393     G4RunManager::ConstructScoringWorlds();
468                                                << 394     
469   GetMasterWorlds().clear();                   << 395     masterWorlds.clear();
470   auto nWorlds = (G4int)G4TransportationManage << 396     size_t nWorlds = G4TransportationManager::GetTransportationManager()->GetNoWorlds();
471   auto itrW = G4TransportationManager::GetTran << 397     std::vector<G4VPhysicalVolume*>::iterator itrW
472   for (G4int iWorld = 0; iWorld < nWorlds; ++i << 398                    = G4TransportationManager::GetTransportationManager()->GetWorldsIterator();
473     addWorld(iWorld, *itrW);                   << 399     for(size_t iWorld=0;iWorld<nWorlds;iWorld++)
474     ++itrW;                                    << 400     {
475   }                                            << 401       addWorld(iWorld,*itrW); 
                                                   >> 402       itrW++;
                                                   >> 403     }
476 }                                                 404 }
477                                                   405 
478 // ------------------------------------------- << 
479 void G4MTRunManager::SetUserInitialization(G4U    406 void G4MTRunManager::SetUserInitialization(G4UserWorkerInitialization* userInit)
480 {                                                 407 {
481   userWorkerInitialization = userInit;            408   userWorkerInitialization = userInit;
482 }                                                 409 }
483                                                   410 
484 // ------------------------------------------- << 
485 void G4MTRunManager::SetUserInitialization(G4U    411 void G4MTRunManager::SetUserInitialization(G4UserWorkerThreadInitialization* userInit)
486 {                                                 412 {
487   userWorkerThreadInitialization = userInit;      413   userWorkerThreadInitialization = userInit;
488 }                                                 414 }
489                                                   415 
490 // ------------------------------------------- << 
491 void G4MTRunManager::SetUserInitialization(G4V    416 void G4MTRunManager::SetUserInitialization(G4VUserActionInitialization* userInit)
492 {                                                 417 {
493   userActionInitialization = userInit;            418   userActionInitialization = userInit;
494   userActionInitialization->BuildForMaster();     419   userActionInitialization->BuildForMaster();
495 }                                                 420 }
496                                                   421 
497 // ------------------------------------------- << 422 void G4MTRunManager::SetUserInitialization(G4VUserPhysicsList *userPL)
498 void G4MTRunManager::SetUserInitialization(G4V << 
499 {                                                 423 {
500   G4RunManager::SetUserInitialization(userPL); << 424     G4RunManager::SetUserInitialization(userPL);
501   // Needed for MT, to be moved in kernel      << 425     //Needed for MT, to be moved in kernel 
502 }                                                 426 }
503                                                   427 
504 // ------------------------------------------- << 428 void G4MTRunManager::SetUserInitialization(G4VUserDetectorConstruction *userDC)
505 void G4MTRunManager::SetUserInitialization(G4V << 
506 {                                                 429 {
507   G4RunManager::SetUserInitialization(userDC); << 430     G4RunManager::SetUserInitialization(userDC);
508 }                                                 431 }
509                                                   432 
510 // ------------------------------------------- << 
511 void G4MTRunManager::SetUserAction(G4UserRunAc    433 void G4MTRunManager::SetUserAction(G4UserRunAction* userAction)
512 {                                                 434 {
513   G4RunManager::SetUserAction(userAction);     << 435     G4RunManager::SetUserAction(userAction); 
514   if (userAction != nullptr) userAction->SetMa << 436     if(userAction) userAction->SetMaster();
515 }                                                 437 }
516                                                   438 
517 // ------------------------------------------- << 
518 void G4MTRunManager::SetUserAction(G4VUserPrim    439 void G4MTRunManager::SetUserAction(G4VUserPrimaryGeneratorAction* /*userAction*/)
519 {                                                 440 {
520   G4Exception("G4MTRunManager::SetUserAction()    441   G4Exception("G4MTRunManager::SetUserAction()", "Run0123", FatalException,
521               "For multi-threaded version, def << 442     "For multi-threaded version, define G4VUserPrimaryGeneratorAction in G4VUserActionInitialization.");
522               "G4VUserActionInitialization."); << 
523 }                                                 443 }
524                                                   444 
525 // ------------------------------------------- << 
526 void G4MTRunManager::SetUserAction(G4UserEvent    445 void G4MTRunManager::SetUserAction(G4UserEventAction* /*userAction*/)
527 {                                                 446 {
528   G4Exception("G4MTRunManager::SetUserAction()    447   G4Exception("G4MTRunManager::SetUserAction()", "Run0124", FatalException,
529               "For multi-threaded version, def << 448     "For multi-threaded version, define G4UserEventAction in G4VUserActionInitialization.");
530               "G4VUserActionInitialization."); << 
531 }                                                 449 }
532                                                   450 
533 // ------------------------------------------- << 
534 void G4MTRunManager::SetUserAction(G4UserStack    451 void G4MTRunManager::SetUserAction(G4UserStackingAction* /*userAction*/)
535 {                                                 452 {
536   G4Exception("G4MTRunManager::SetUserAction()    453   G4Exception("G4MTRunManager::SetUserAction()", "Run0125", FatalException,
537               "For multi-threaded version, def << 454     "For multi-threaded version, define G4UserStackingAction in G4VUserActionInitialization.");
538               "G4VUserActionInitialization."); << 
539 }                                                 455 }
540                                                   456 
541 // ------------------------------------------- << 
542 void G4MTRunManager::SetUserAction(G4UserTrack    457 void G4MTRunManager::SetUserAction(G4UserTrackingAction* /*userAction*/)
543 {                                                 458 {
544   G4Exception("G4MTRunManager::SetUserAction()    459   G4Exception("G4MTRunManager::SetUserAction()", "Run0126", FatalException,
545               "For multi-threaded version, def << 460     "For multi-threaded version, define G4UserTrackingAction in G4VUserActionInitialization.");
546               "G4VUserActionInitialization."); << 
547 }                                                 461 }
548                                                   462 
549 // ------------------------------------------- << 
550 void G4MTRunManager::SetUserAction(G4UserStepp    463 void G4MTRunManager::SetUserAction(G4UserSteppingAction* /*userAction*/)
551 {                                                 464 {
552   G4Exception("G4MTRunManager::SetUserAction()    465   G4Exception("G4MTRunManager::SetUserAction()", "Run0127", FatalException,
553               "For multi-threaded version, def << 466     "For multi-threaded version, define G4UserSteppingAction in G4VUserActionInitialization.");
554               "G4VUserActionInitialization."); << 
555 }                                                 467 }
556                                                   468 
557 // ------------------------------------------- << 
558 void G4MTRunManager::MergeScores(const G4Scori    469 void G4MTRunManager::MergeScores(const G4ScoringManager* localScoringManager)
559 {                                                 470 {
560   G4AutoLock l(&scorerMergerMutex);               471   G4AutoLock l(&scorerMergerMutex);
561   if (masterScM != nullptr && localScoringMana << 472   if(masterScM) masterScM->Merge(localScoringManager); 
562 }                                                 473 }
563                                                   474 
564 // ------------------------------------------- << 
565 void G4MTRunManager::MergeRun(const G4Run* loc    475 void G4MTRunManager::MergeRun(const G4Run* localRun)
566 {                                                 476 {
567   G4AutoLock l(&runMergerMutex);                  477   G4AutoLock l(&runMergerMutex);
568   if (currentRun != nullptr && localRun != nul << 478   if(currentRun) currentRun->Merge(localRun); 
569 }                                                 479 }
570                                                   480 
571 // ------------------------------------------- << 481 G4bool G4MTRunManager::SetUpAnEvent(G4Event* evt,long& s1,long& s2,long& s3,G4bool reseedRequired)
572 G4bool G4MTRunManager::SetUpAnEvent(G4Event* e << 
573                                     G4bool res << 
574 {                                                 482 {
575   G4AutoLock l(&setUpEventMutex);                 483   G4AutoLock l(&setUpEventMutex);
576   if (numberOfEventProcessed < numberOfEventTo << 484   if( numberOfEventProcessed < numberOfEventToBeProcessed )
                                                   >> 485   {
577     evt->SetEventID(numberOfEventProcessed);      486     evt->SetEventID(numberOfEventProcessed);
578     if (reseedRequired) {                      << 487     if(reseedRequired)
                                                   >> 488     {
579       G4RNGHelper* helper = G4RNGHelper::GetIn    489       G4RNGHelper* helper = G4RNGHelper::GetInstance();
580       G4int idx_rndm = nSeedsPerEvent * nSeeds << 490       G4int idx_rndm = nSeedsPerEvent*nSeedsUsed;
581       s1 = helper->GetSeed(idx_rndm);             491       s1 = helper->GetSeed(idx_rndm);
582       s2 = helper->GetSeed(idx_rndm + 1);      << 492       s2 = helper->GetSeed(idx_rndm+1);
583       if (nSeedsPerEvent == 3) s3 = helper->Ge << 493       if(nSeedsPerEvent==3) s3 = helper->GetSeed(idx_rndm+2);
584       ++nSeedsUsed;                            << 494       nSeedsUsed++;
585       if (nSeedsUsed == nSeedsFilled) RefillSe << 495       if(nSeedsUsed==nSeedsFilled) RefillSeeds();
586     }                                             496     }
587     ++numberOfEventProcessed;                  << 497     numberOfEventProcessed++;
588     return true;                                  498     return true;
589   }                                               499   }
590   return false;                                   500   return false;
591 }                                                 501 }
592                                                   502 
593 // ------------------------------------------- << 503 G4int G4MTRunManager::SetUpNEvents(G4Event* evt, G4SeedsQueue* seedsQueue,G4bool reseedRequired)
594 G4int G4MTRunManager::SetUpNEvents(G4Event* ev << 
595 {                                                 504 {
596   G4AutoLock l(&setUpEventMutex);                 505   G4AutoLock l(&setUpEventMutex);
597   if (numberOfEventProcessed < numberOfEventTo << 506   if( numberOfEventProcessed < numberOfEventToBeProcessed && !runAborted )
                                                   >> 507   {
598     G4int nev = eventModulo;                      508     G4int nev = eventModulo;
599     if (numberOfEventProcessed + nev > numberO << 509     if(numberOfEventProcessed + nev > numberOfEventToBeProcessed)
600       nev = numberOfEventToBeProcessed - numbe << 510     { nev = numberOfEventToBeProcessed - numberOfEventProcessed; }
601     }                                          << 
602     evt->SetEventID(numberOfEventProcessed);      511     evt->SetEventID(numberOfEventProcessed);
603     if (reseedRequired) {                      << 512     if(reseedRequired)
                                                   >> 513     {
604       G4RNGHelper* helper = G4RNGHelper::GetIn    514       G4RNGHelper* helper = G4RNGHelper::GetInstance();
605       G4int nevRnd = nev;                         515       G4int nevRnd = nev;
606       if (seedOncePerCommunication > 0) nevRnd << 516       if(seedOncePerCommunication>0) nevRnd = 1;
607       for (G4int i = 0; i < nevRnd; ++i) {     << 517       for(int i=0;i<nevRnd;i++)
608         seedsQueue->push(helper->GetSeed(nSeed << 518       {
609         seedsQueue->push(helper->GetSeed(nSeed << 519         seedsQueue->push(helper->GetSeed(nSeedsPerEvent*nSeedsUsed));
610         if (nSeedsPerEvent == 3) seedsQueue->p << 520         seedsQueue->push(helper->GetSeed(nSeedsPerEvent*nSeedsUsed+1));
611         ++nSeedsUsed;                          << 521         if(nSeedsPerEvent==3)
612         if (nSeedsUsed == nSeedsFilled) Refill << 522           seedsQueue->push(helper->GetSeed(nSeedsPerEvent*nSeedsUsed+2));
                                                   >> 523         nSeedsUsed++;
                                                   >> 524         if(nSeedsUsed==nSeedsFilled) RefillSeeds();
613       }                                           525       }
614     }                                             526     }
615     numberOfEventProcessed += nev;                527     numberOfEventProcessed += nev;
616     return nev;                                   528     return nev;
617   }                                               529   }
618   return 0;                                       530   return 0;
619 }                                                 531 }
620                                                   532 
621 // ------------------------------------------- << 
622 void G4MTRunManager::TerminateWorkers()           533 void G4MTRunManager::TerminateWorkers()
623 {                                                 534 {
624   // Force workers to execute (if any) all UI  << 535     //Force workers to execute (if any) all UI commands left in the stack
625   RequestWorkersProcessCommandsStack();        << 536     RequestWorkersProcessCommandsStack();
626   // Ask workers to exit                       << 537     //Ask workers to exit
627   NewActionRequest(WorkerActionRequest::ENDWOR << 538     NewActionRequest( WorkerActionRequest::ENDWORKER );
628   // Now join threads.                         << 539     //Now join threads.
629 #ifdef G4MULTITHREADED  // protect here to pre << 540 #ifdef G4MULTITHREADED //protect here to prevent warning in compilation
630   while (!threads.empty()) {                   << 541     while ( ! threads.empty() )
631     G4Thread* t = *(threads.begin());          << 542     {
632     threads.pop_front();                       << 543         G4Thread* t = * ( threads.begin() );
633     userWorkerThreadInitialization->JoinWorker << 544         threads.pop_front();
634     delete t;                                  << 545         userWorkerThreadInitialization->JoinWorker(t);
635   }                                            << 546         //G4THREADJOIN(*t);
                                                   >> 547         delete t;
                                                   >> 548     }
636 #endif                                            549 #endif
637   threads.clear();                             << 550     threads.clear();
638 }                                                 551 }
639                                                   552 
640 // ------------------------------------------- << 
641 void G4MTRunManager::AbortRun(G4bool softAbort    553 void G4MTRunManager::AbortRun(G4bool softAbort)
642 {                                                 554 {
643   // This method is valid only for GeomClosed     555   // This method is valid only for GeomClosed or EventProc state
644   G4ApplicationState currentState = G4StateMan << 556   G4ApplicationState currentState =
645   if (currentState == G4State_GeomClosed || cu << 557     G4StateManager::GetStateManager()->GetCurrentState();
                                                   >> 558   if(currentState==G4State_GeomClosed || currentState==G4State_EventProc)
                                                   >> 559   {
646     runAborted = true;                            560     runAborted = true;
647     MTkernel->BroadcastAbortRun(softAbort);       561     MTkernel->BroadcastAbortRun(softAbort);
648   }                                               562   }
649   else {                                       << 563   else
                                                   >> 564   {
650     G4cerr << "Run is not in progress. AbortRu    565     G4cerr << "Run is not in progress. AbortRun() ignored." << G4endl;
651   }                                               566   }
652 }                                                 567 }
653                                                   568 
654 // ------------------------------------------- << 
655 void G4MTRunManager::AbortEvent()                 569 void G4MTRunManager::AbortEvent()
656 {                                                 570 {
657   // nothing to do in the master thread           571   // nothing to do in the master thread
658 }                                                 572 }
659                                                   573 
660 // ------------------------------------------- << 574 void G4MTRunManager::WaitForReadyWorkers() {
661 void G4MTRunManager::WaitForReadyWorkers()     << 575   beginOfEventLoopBarrier.Wait( GetNumberActiveThreads() );
662 {                                              << 
663   beginOfEventLoopBarrier.Wait((G4int)GetNumbe << 
664   endOfEventLoopBarrier.ResetCounter();           576   endOfEventLoopBarrier.ResetCounter();
665   beginOfEventLoopBarrier.ReleaseBarrier();       577   beginOfEventLoopBarrier.ReleaseBarrier();
666 }                                                 578 }
667                                                   579 
668 // ------------------------------------------- << 580 void G4MTRunManager::ThisWorkerReady() {
669 void G4MTRunManager::ThisWorkerReady()         << 
670 {                                              << 
671   beginOfEventLoopBarrier.ThisWorkerReady();      581   beginOfEventLoopBarrier.ThisWorkerReady();
672 }                                                 582 }
673                                                   583 
674 // ------------------------------------------- << 584 void G4MTRunManager::WaitForEndEventLoopWorkers() {
675 void G4MTRunManager::WaitForEndEventLoopWorker << 585   endOfEventLoopBarrier.Wait( GetNumberActiveThreads() );
676 {                                              << 
677   endOfEventLoopBarrier.Wait((G4int)GetNumberA << 
678   beginOfEventLoopBarrier.ResetCounter();         586   beginOfEventLoopBarrier.ResetCounter();
679   endOfEventLoopBarrier.ReleaseBarrier();         587   endOfEventLoopBarrier.ReleaseBarrier();
680 }                                                 588 }
681                                                   589 
682 // ------------------------------------------- << 590 void G4MTRunManager::ThisWorkerEndEventLoop() {
683 void G4MTRunManager::ThisWorkerEndEventLoop()  << 
684 {                                              << 
685   endOfEventLoopBarrier.ThisWorkerReady();        591   endOfEventLoopBarrier.ThisWorkerReady();
686 }                                                 592 }
687                                                   593 
688 // ------------------------------------------- << 594 void G4MTRunManager::NewActionRequest(G4MTRunManager::WorkerActionRequest newRequest) {
689 void G4MTRunManager::NewActionRequest(G4MTRunM << 595    nextActionRequestBarrier.Wait( GetNumberActiveThreads() );
690 {                                              << 596    //nextActionRequest is a shared resource, but there is no
691   nextActionRequestBarrier.Wait((G4int)GetNumb << 597    //data-race thanks to the barrier: all threads are waiting
692   // nextActionRequest is a shared resource, b << 598    nextActionRequest = newRequest;
693   // data-race thanks to the barrier: all thre << 599    nextActionRequestBarrier.ReleaseBarrier();
694   nextActionRequest = newRequest;              << 
695   nextActionRequestBarrier.ReleaseBarrier();   << 
696 }                                                 600 }
697                                                   601 
698 // ------------------------------------------- << 602 G4MTRunManager::WorkerActionRequest G4MTRunManager::ThisWorkerWaitForNextAction() {
699 G4MTRunManager::WorkerActionRequest G4MTRunMan << 
700 {                                              << 
701   nextActionRequestBarrier.ThisWorkerReady();     603   nextActionRequestBarrier.ThisWorkerReady();
702   return nextActionRequest;                       604   return nextActionRequest;
703 }                                                 605 }
704                                                   606 
705 // ------------------------------------------- << 607 void G4MTRunManager::RequestWorkersProcessCommandsStack() {
706 void G4MTRunManager::RequestWorkersProcessComm << 
707 {                                              << 
708   PrepareCommandsStack();                         608   PrepareCommandsStack();
709   NewActionRequest(WorkerActionRequest::PROCES    609   NewActionRequest(WorkerActionRequest::PROCESSUI);
710   processUIBarrier.SetActiveThreads((G4int)Get << 610   processUIBarrier.SetActiveThreads( GetNumberActiveThreads() );
711   processUIBarrier.WaitForReadyWorkers();         611   processUIBarrier.WaitForReadyWorkers();
712 }                                                 612 }
713                                                   613 
714 // ------------------------------------------- << 614 void G4MTRunManager::ThisWorkerProcessCommandsStackDone() {
715 void G4MTRunManager::ThisWorkerProcessCommands << 
716 {                                              << 
717   processUIBarrier.ThisWorkerReady();             615   processUIBarrier.ThisWorkerReady();
718 }                                                 616 }
719                                                << 
720 // ------------------------------------------- << 
721 void G4MTRunManager::SetPinAffinity(G4int n)      617 void G4MTRunManager::SetPinAffinity(G4int n)
722 {                                                 618 {
723   if (n == 0) {                                << 619   if ( n == 0 )
724     G4Exception("G4MTRunManager::SetPinAffinit << 620   {
725                 "Pin affinity must be >0 or <0 << 621     G4Exception("G4MTRunManager::SetPinAffinity",
726   }                                            << 622           "Run0114",FatalException,
727   pinAffinity = n;                             << 623           "Pin affinity must be >0 or <0.");
728   return;                                      << 624   }
                                                   >> 625   pinAffinity = n;
                                                   >> 626   return;
729 }                                                 627 }
730                                                   628