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