Geant4 Cross Reference |
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