CMS 3D CMS Logo

OscarMTMasterThread.cc
Go to the documentation of this file.
2 
5 
10 
14 
15 #include "HepPDT/ParticleDataTable.hh"
17 
18 #include "G4PhysicalVolumeStore.hh"
19 
21  : m_pGeoFromDD4hep(iConfig.getParameter<bool>("g4GeometryDD4hepSource")),
22  m_pDD(nullptr),
23  m_pDD4hep(nullptr),
24  m_pTable(nullptr),
25  m_masterThreadState(ThreadState::NotExist),
26  m_masterCanProceed(false),
27  m_mainCanProceed(false),
28  m_firstRun(true),
29  m_stopped(false) {
30  // Lock the mutex
31  std::unique_lock<std::mutex> lk(m_threadMutex);
32 
33  edm::LogInfo("SimG4CoreApplication") << "OscarMTMasterThread: creating master thread";
34 
35  // Create Genat4 master thread
36  m_masterThread = std::thread([&]() {
38  // Initialization
39 
40  std::shared_ptr<RunManagerMT> runManagerMaster;
41  std::unique_ptr<CustomUIsession> uiSession;
42 
43  // Lock the mutex (i.e. wait until the creating thread has called cv.wait()
44  std::unique_lock<std::mutex> lk2(m_threadMutex);
45 
46  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: initializing RunManagerMT";
47 
48  //UIsession manager for message handling
49  uiSession.reset(new CustomUIsession());
50 
51  // Create the master run manager, and share it to the CMSSW thread
52  runManagerMaster = std::make_shared<RunManagerMT>(iConfig);
54 
55  LogDebug("SimG4CoreApplication") << "OscarMTMasterThread: initialization of RunManagerMT finished";
56 
58  // State loop
59  bool isG4Alive = false;
60  while (true) {
61  // Signal main thread that it can proceed
62  m_mainCanProceed = true;
63  edm::LogVerbatim("OscarMTMasterThread") << "Master thread: State loop, notify main thread";
64  m_notifyMainCv.notify_one();
65 
66  // Wait until the main thread sends signal
67  m_masterCanProceed = false;
68  edm::LogVerbatim("OscarMTMasterThread") << "Master thread: State loop, starting wait";
69  m_notifyMasterCv.wait(lk2, [&] { return m_masterCanProceed; });
70 
71  // Act according to the state
72  edm::LogInfo("OscarMTMasterThread")
73  << "Master thread: Woke up, state is " << static_cast<int>(m_masterThreadState);
75  // Initialize Geant4
76  edm::LogInfo("OscarMTMasterThread") << "Master thread: Initializing Geant4";
78  isG4Alive = true;
80  // Stop Geant4
81  LogDebug("OscarMTMasterThread") << "Master thread: Stopping Geant4";
83  isG4Alive = false;
85  LogDebug("OscarMTMasterThread") << "Master thread: Breaking out of state loop";
86  if (isG4Alive)
88  << "Geant4 is still alive, master thread state must be set to EndRun before Destruct";
89  break;
90  } else {
92  << "OscarMTMasterThread: Illegal master thread state " << static_cast<int>(m_masterThreadState);
93  }
94  }
95 
97  // Cleanup
98  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: start RunManagerMT destruction";
99  LogDebug("OscarMTMasterThread") << "Master thread: Am I unique owner of runManagerMaster? "
100  << runManagerMaster.unique();
101 
102  // must be done in this thread, segfault otherwise
103  runManagerMaster.reset();
104  G4PhysicalVolumeStore::Clean();
105 
106  LogDebug("OscarMTMasterThread") << "Master thread: Reseted shared_ptr";
107  lk2.unlock();
108  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: Master thread is finished";
109  });
110 
111  // Start waiting a signal from the condition variable (releases the lock temporarily)
112  // First for initialization
113  m_mainCanProceed = false;
114  LogDebug("OscarMTMasterThread") << "Main thread: Signal master for initialization";
115  m_notifyMainCv.wait(lk, [&]() { return m_mainCanProceed; });
116 
117  lk.unlock();
118  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: Master thread is constructed";
119 }
120 
122  if (!m_stopped) {
123  stopThread();
124  }
125 }
126 
128  std::lock_guard<std::mutex> lk(m_protectMutex);
129 
130  std::unique_lock<std::mutex> lk2(m_threadMutex);
131 
132  // Reading from ES must be done in the main (CMSSW) thread
133  readES(iSetup);
134 
136  m_masterCanProceed = true;
137  m_mainCanProceed = false;
138  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: Signal master for BeginRun";
139  m_notifyMasterCv.notify_one();
140  m_notifyMainCv.wait(lk2, [&]() { return m_mainCanProceed; });
141 
142  lk2.unlock();
143  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: finish BeginRun";
144 }
145 
147  std::lock_guard<std::mutex> lk(m_protectMutex);
148 
149  std::unique_lock<std::mutex> lk2(m_threadMutex);
151  m_mainCanProceed = false;
152  m_masterCanProceed = true;
153  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: Signal master for EndRun";
154  m_notifyMasterCv.notify_one();
155  m_notifyMainCv.wait(lk2, [&]() { return m_mainCanProceed; });
156  lk2.unlock();
157  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: finish EndRun";
158 }
159 
161  if (m_stopped) {
162  return;
163  }
164  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread::stopTread: stop main thread";
165 
166  // Release our instance of the shared master run manager, so that
167  // the G4 master thread can do the cleanup. Then notify the master
168  // thread, and join it.
169  std::unique_lock<std::mutex> lk2(m_threadMutex);
170  m_runManagerMaster.reset();
171  LogDebug("OscarMTMasterThread") << "Main thread: reseted shared_ptr";
172 
174  m_masterCanProceed = true;
175  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread::stopTread: notify";
176  m_notifyMasterCv.notify_one();
177  lk2.unlock();
178 
179  LogDebug("OscarMTMasterThread") << "Main thread: joining master thread";
180  m_masterThread.join();
181  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread::stopTread: main thread finished";
182  m_stopped = true;
183 }
184 
185 void OscarMTMasterThread::readES(const edm::EventSetup& iSetup) const {
186  bool geomChanged = idealGeomRcdWatcher_.check(iSetup);
187  if (geomChanged && (!m_firstRun)) {
189  << "[SimG4Core OscarMTMasterThread]\n"
190  << "The Geometry configuration is changed during the job execution\n"
191  << "this is not allowed, the geometry must stay unchanged";
192  }
193  // Don't read from ES if not the first run, just as in
194  if (!m_firstRun)
195  return;
196 
197  // DDDWorld: get the DDCV from the ES and use it to build the World
198  if (m_pGeoFromDD4hep) {
200  iSetup.get<IdealGeometryRecord>().get(pDD);
201  m_pDD4hep = pDD.product();
202  } else {
204  iSetup.get<IdealGeometryRecord>().get(pDD);
205  m_pDD = pDD.product();
206  }
207 
209  iSetup.get<PDTRecord>().get(fTable);
210  m_pTable = fTable.product();
211 
212  m_firstRun = false;
213 }
edm::ESWatcher::check
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:52
edm::ESHandle::product
T const * product() const
Definition: ESHandle.h:86
OscarMTMasterThread::m_notifyMasterCv
std::condition_variable m_notifyMasterCv
Definition: OscarMTMasterThread.h:63
electrons_cff.bool
bool
Definition: electrons_cff.py:372
OscarMTMasterThread::m_masterThread
std::thread m_masterThread
Definition: OscarMTMasterThread.h:52
ESTransientHandle.h
funct::false
false
Definition: Factorize.h:34
edm::ESTransientHandle::product
T const * product() const
Definition: ESTransientHandle.h:51
ESHandle.h
edm::errors::LogicError
Definition: EDMException.h:37
OscarMTMasterThread::m_firstRun
bool m_firstRun
Definition: OscarMTMasterThread.h:70
edm::LogInfo
Definition: MessageLogger.h:254
OscarMTMasterThread::OscarMTMasterThread
OscarMTMasterThread(const edm::ParameterSet &iConfig)
Definition: OscarMTMasterThread.cc:20
OscarMTMasterThread.h
OscarMTMasterThread::ThreadState::BeginRun
OscarMTMasterThread::endRun
void endRun() const
Definition: OscarMTMasterThread.cc:146
DDCompactView.h
EDMException.h
OscarMTMasterThread::ThreadState
ThreadState
Definition: OscarMTMasterThread.h:47
OscarMTMasterThread::ThreadState::EndRun
OscarMTMasterThread::m_masterThreadState
ThreadState m_masterThreadState
Definition: OscarMTMasterThread.h:66
edm::EventSetup::get
T get() const
Definition: EventSetup.h:73
g4SimHits_cfi.CustomUIsession
CustomUIsession
Definition: g4SimHits_cfi.py:84
OscarMTMasterThread::m_mainCanProceed
bool m_mainCanProceed
Definition: OscarMTMasterThread.h:69
edm::ESHandle< HepPDT::ParticleDataTable >
OscarMTMasterThread::m_runManagerMaster
std::shared_ptr< RunManagerMT > m_runManagerMaster
Definition: OscarMTMasterThread.h:51
CustomUIsession.h
DDCompactView.h
funct::true
true
Definition: Factorize.h:173
OscarMTMasterThread::stopThread
void stopThread()
Definition: OscarMTMasterThread.cc:160
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:670
edm::ParameterSet
Definition: ParameterSet.h:36
OscarMTMasterThread::runManagerMaster
RunManagerMT & runManagerMaster() const
Definition: OscarMTMasterThread.h:41
RunManagerMT::initG4
void initG4(const DDCompactView *, const cms::DDCompactView *, const HepPDT::ParticleDataTable *)
Definition: RunManagerMT.cc:92
OscarMTMasterThread::m_protectMutex
std::mutex m_protectMutex
Definition: OscarMTMasterThread.h:61
RunManagerMT.h
OscarMTMasterThread::~OscarMTMasterThread
~OscarMTMasterThread()
Definition: OscarMTMasterThread.cc:121
OscarMTMasterThread::m_stopped
bool m_stopped
Definition: OscarMTMasterThread.h:71
edm::LogVerbatim
Definition: MessageLogger.h:297
IdealGeometryRecord.h
edm::EventSetup
Definition: EventSetup.h:57
get
#define get
OscarMTMasterThread::m_pDD
const DDCompactView * m_pDD
Definition: OscarMTMasterThread.h:57
edm::ESTransientHandle
Definition: ESTransientHandle.h:41
OscarMTMasterThread::m_masterCanProceed
bool m_masterCanProceed
Definition: OscarMTMasterThread.h:68
OscarMTMasterThread::m_pGeoFromDD4hep
const bool m_pGeoFromDD4hep
Definition: OscarMTMasterThread.h:49
Exception
Definition: hltDiff.cc:246
OscarMTMasterThread::m_pDD4hep
const cms::DDCompactView * m_pDD4hep
Definition: OscarMTMasterThread.h:58
EventSetup.h
OscarMTMasterThread::beginRun
void beginRun(const edm::EventSetup &iSetup) const
Definition: OscarMTMasterThread.cc:127
OscarMTMasterThread::m_pTable
const HepPDT::ParticleDataTable * m_pTable
Definition: OscarMTMasterThread.h:59
PDTRecord.h
OscarMTMasterThread::readES
void readES(const edm::EventSetup &iSetup) const
Definition: OscarMTMasterThread.cc:185
RunManagerMT::stopG4
void stopG4()
Definition: RunManagerMT.cc:253
OscarMTMasterThread::idealGeomRcdWatcher_
edm::ESWatcher< IdealGeometryRecord > idealGeomRcdWatcher_
Definition: OscarMTMasterThread.h:55
OscarMTMasterThread::m_threadMutex
std::mutex m_threadMutex
Definition: OscarMTMasterThread.h:62
edm::errors::Configuration
Definition: EDMException.h:36
PDTRecord
Definition: PDTRecord.h:14
OscarMTMasterThread::m_notifyMainCv
std::condition_variable m_notifyMainCv
Definition: OscarMTMasterThread.h:64
OscarMTMasterThread::ThreadState::Destruct
IdealGeometryRecord
Definition: IdealGeometryRecord.h:27