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