diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/ATLAS_CHECK_THREAD_SAFETY b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/ATLAS_CHECK_THREAD_SAFETY new file mode 100644 index 0000000000000000000000000000000000000000..4818d903975bf78bcd424a53fadbf7a9425d06c0 --- /dev/null +++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/ATLAS_CHECK_THREAD_SAFETY @@ -0,0 +1 @@ +Simulation/G4Atlas/G4AtlasAlg diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasMTRunManager.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasMTRunManager.h index bcf0586c9147d2daf3accb109b87a8378251a4a4..40af0672a17d4758e934f5110da1f7d2e0889de9 100644 --- a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasMTRunManager.h +++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasMTRunManager.h @@ -16,6 +16,7 @@ #include "GaudiKernel/ToolHandle.h" #include "GaudiKernel/ServiceHandle.h" #include "AthenaBaseComps/AthMessaging.h" +#include "CxxUtils/checker_macros.h" // G4Atlas includes #include "G4AtlasInterfaces/IPhysicsListSvc.h" @@ -38,7 +39,7 @@ class G4AtlasMTRunManager: public G4MTRunManager, public AthMessaging { public: /// Get the (pure) singleton instance - static G4AtlasMTRunManager* GetG4AtlasMTRunManager(); + static G4AtlasMTRunManager* GetG4AtlasMTRunManager ATLAS_NOT_THREAD_SAFE (); /// G4 function called at end of run void RunTermination() override final; diff --git a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasRunManager.h b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasRunManager.h index da857be8d49930fc2c15e30562f2c435a1c1b979..c4b50d29e6ebeb76ba9a2dab0711c2e6f109432c 100644 --- a/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasRunManager.h +++ b/Simulation/G4Atlas/G4AtlasAlg/G4AtlasAlg/G4AtlasRunManager.h @@ -14,6 +14,7 @@ // Athena headers #include "AthenaBaseComps/AthMessaging.h" +#include "CxxUtils/checker_macros.h" #include "G4AtlasInterfaces/ISensitiveDetectorMasterTool.h" #include "G4AtlasInterfaces/IFastSimulationMasterTool.h" #include "G4AtlasInterfaces/IPhysicsListSvc.h" @@ -33,7 +34,7 @@ public: virtual ~G4AtlasRunManager() {} /// Retrieve the singleton instance - static G4AtlasRunManager* GetG4AtlasRunManager(); + static G4AtlasRunManager* GetG4AtlasRunManager ATLAS_NOT_THREAD_SAFE (); /// Does the work of simulating an ATLAS event bool ProcessEvent(G4Event* event); diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx index d7554c79da654dcbe49ff7a738f3079ccfe92951..cd077b095d5d4437ba26ea934eeb22d97f7f4f0f 100644 --- a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx +++ b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx @@ -8,6 +8,7 @@ #include "G4AtlasAlg/G4AtlasActionInitialization.h" #include "AthenaKernel/RNGWrapper.h" +#include "CxxUtils/checker_macros.h" // Can we safely include all of these? #include "G4AtlasAlg/G4AtlasMTRunManager.h" @@ -114,7 +115,8 @@ void G4AtlasAlg::initializeOnce() // Create the (master) run manager if(m_useMT) { #ifdef G4MULTITHREADED - auto* runMgr = G4AtlasMTRunManager::GetG4AtlasMTRunManager(); + auto* runMgr ATLAS_THREAD_SAFE = // protected by std::call_once above + G4AtlasMTRunManager::GetG4AtlasMTRunManager(); m_physListSvc->SetPhysicsList(); runMgr->SetDetGeoSvc( m_detGeoSvc.typeAndName() ); runMgr->SetFastSimMasterTool(m_fastSimTool.typeAndName() ); @@ -134,7 +136,8 @@ void G4AtlasAlg::initializeOnce() } // Single-threaded run manager else { - auto* runMgr = G4AtlasRunManager::GetG4AtlasRunManager(); + auto* runMgr ATLAS_THREAD_SAFE = // safe because single-threaded + G4AtlasRunManager::GetG4AtlasRunManager(); m_physListSvc->SetPhysicsList(); runMgr->SetRecordFlux( m_recordFlux, std::make_unique<G4AtlasFluxRecorder>() ); runMgr->SetLogLevel( int(msg().level()) ); // Synch log levels @@ -275,7 +278,7 @@ void G4AtlasAlg::finalizeOnce() StatusCode G4AtlasAlg::execute() { - static int n_Event=0; + static std::atomic<unsigned int> n_Event=0; ATH_MSG_DEBUG("++++++++++++ G4AtlasAlg execute ++++++++++++"); #ifdef G4MULTITHREADED @@ -357,7 +360,8 @@ StatusCode G4AtlasAlg::execute() #endif } else { - auto* workerRM = G4AtlasRunManager::GetG4AtlasRunManager(); + auto* workerRM ATLAS_THREAD_SAFE = // single-threaded case + G4AtlasRunManager::GetG4AtlasRunManager(); abort = workerRM->ProcessEvent(inputEvent); } if (abort) { diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasMTRunManager.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasMTRunManager.cxx index 656c8686afe1eef5f395a4906567195d39b1265d..1023a73b5c4d33da7dad5040c0e8e2f1edc496b5 100644 --- a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasMTRunManager.cxx +++ b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasMTRunManager.cxx @@ -31,7 +31,7 @@ G4AtlasMTRunManager::G4AtlasMTRunManager() {} -G4AtlasMTRunManager* G4AtlasMTRunManager::GetG4AtlasMTRunManager() +G4AtlasMTRunManager* G4AtlasMTRunManager::GetG4AtlasMTRunManager ATLAS_NOT_THREAD_SAFE () { static G4AtlasMTRunManager* thisManager = nullptr; if (!thisManager) { thisManager = new G4AtlasMTRunManager; } diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasRunManager.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasRunManager.cxx index 5ac05962741bda09a01a29f7ba73fae982f2f65c..4f158fc6a5115347556b1a11c0aa315dfb472a54 100644 --- a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasRunManager.cxx +++ b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasRunManager.cxx @@ -30,7 +30,7 @@ G4AtlasRunManager::G4AtlasRunManager() { } -G4AtlasRunManager* G4AtlasRunManager::GetG4AtlasRunManager() +G4AtlasRunManager* G4AtlasRunManager::GetG4AtlasRunManager ATLAS_NOT_THREAD_SAFE () { static G4AtlasRunManager *thisManager = nullptr; if (!thisManager) { thisManager = new G4AtlasRunManager; } // Leaked diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasWorkerRunManager.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasWorkerRunManager.cxx index 7126ee071e156f19bc9aaf6e2275c99719125fe1..2c14ef6341fcecc7f280b3b29a0a0851facc9d3b 100644 --- a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasWorkerRunManager.cxx +++ b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasWorkerRunManager.cxx @@ -95,7 +95,7 @@ void G4AtlasWorkerRunManager::InitializeGeometry() const std::string methodName = "G4AtlasWorkerRunManager::InitializeGeometry"; // I don't think this does anything - if(fGeometryHasBeenDestroyed) { + if(G4RunManager::IfGeometryHasBeenDestroyed()) { G4TransportationManager::GetTransportationManager()->ClearParallelWorlds(); }