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.6)


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