CMS 3D CMS Logo

OscarMTMasterThread.cc
Go to the documentation of this file.
1 #include <memory>
2 
6 
9 
10 #include "G4PhysicalVolumeStore.hh"
11 
13  : m_pGeoFromDD4hep(iConfig.getParameter<bool>("g4GeometryDD4hepSource")),
14  m_masterThreadState(ThreadState::NotExist) {
15  // Lock the mutex
16  std::unique_lock<std::mutex> lk(m_threadMutex);
17 
18  edm::LogVerbatim("SimG4CoreApplication")
19  << "OscarMTMasterThread: creating master thread DD4Hep: " << m_pGeoFromDD4hep;
20 
21  // Create Geant4 master thread
22  m_masterThread = std::thread([&]() {
24  // Initialization
25  std::unique_ptr<CustomUIsession> uiSession;
26 
27  // Lock the mutex (i.e. wait until the creating thread has called cv.wait()
28  std::unique_lock<std::mutex> lk2(m_threadMutex);
29 
30  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: initializing RunManagerMT";
31 
32  //UIsession manager for message handling
33  uiSession = std::make_unique<CustomUIsession>();
34 
35  // Create the master run manager, and share it to the CMSSW thread
36  m_runManagerMaster = std::make_shared<RunManagerMT>(iConfig);
37 
39  // State loop
40  bool isG4Alive = false;
41  while (true) {
42  // Signal main thread that it can proceed
43  m_mainCanProceed = true;
44  edm::LogVerbatim("OscarMTMasterThread") << "Master thread: State loop, notify main thread";
45  m_notifyMainCv.notify_one();
46 
47  // Wait until the main thread sends signal
48  m_masterCanProceed = false;
49  edm::LogVerbatim("OscarMTMasterThread") << "Master thread: State loop, starting wait";
50  m_notifyMasterCv.wait(lk2, [&] { return m_masterCanProceed; });
51  //m_notifyMasterCv.wait(lk2, [&] { return false; });
52 
53  // Act according to the state
54  edm::LogVerbatim("OscarMTMasterThread")
55  << "Master thread: Woke up, state is " << static_cast<int>(m_masterThreadState);
57  // Initialize Geant4
58  edm::LogVerbatim("OscarMTMasterThread") << "Master thread: Initializing Geant4";
60  isG4Alive = true;
62  // Stop Geant4
63  edm::LogVerbatim("OscarMTMasterThread") << "Master thread: Stopping Geant4";
64  m_runManagerMaster->stopG4();
65  isG4Alive = false;
67  edm::LogVerbatim("OscarMTMasterThread") << "Master thread: Breaking out of state loop";
68  if (isG4Alive)
70  << "Geant4 is still alive, master thread state must be set to EndRun before Destruct";
71  break;
72  } else {
74  << "OscarMTMasterThread: Illegal master thread state " << static_cast<int>(m_masterThreadState);
75  }
76  }
77 
79  // Cleanup
80  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: start RunManagerMT destruction";
81 
82  // must be done in this thread, segfault otherwise
83  m_runManagerMaster.reset();
84  G4PhysicalVolumeStore::Clean();
85 
86  edm::LogVerbatim("OscarMTMasterThread") << "Master thread: Reseted shared_ptr";
87  lk2.unlock();
88  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: Master thread is finished";
89  });
90 
91  // Start waiting a signal from the condition variable (releases the lock temporarily)
92  // First for initialization
93  m_mainCanProceed = false;
94  LogDebug("OscarMTMasterThread") << "Main thread: Signal master for initialization";
95  m_notifyMainCv.wait(lk, [&]() { return m_mainCanProceed; });
96 
97  lk.unlock();
98  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: Master thread is constructed";
99 }
100 
102  if (!m_stopped) {
103  stopThread();
104  }
105 }
106 
108  if (m_hasToken) {
109  return;
110  }
111  if (m_pGeoFromDD4hep) {
113  } else {
115  }
117  m_hasToken = true;
118 }
119 
121  std::lock_guard<std::mutex> lk(m_protectMutex);
122  std::unique_lock<std::mutex> lk2(m_threadMutex);
123  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread::beginRun";
124 
125  if (m_firstRun) {
126  if (m_pGeoFromDD4hep) {
127  m_pDD4Hep = &(*iSetup.getTransientHandle(m_DD4Hep));
128  } else {
129  m_pDDD = &(*iSetup.getTransientHandle(m_DDD));
130  }
131  m_pTable = &iSetup.getData(m_PDT);
132  m_firstRun = false;
133  }
135  m_masterCanProceed = true;
136  m_mainCanProceed = false;
137  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: Signal master for BeginRun";
138  m_notifyMasterCv.notify_one();
139  m_notifyMainCv.wait(lk2, [&]() { return m_mainCanProceed; });
140 
141  lk2.unlock();
142  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: finish BeginRun";
143 }
144 
146  std::lock_guard<std::mutex> lk(m_protectMutex);
147  std::unique_lock<std::mutex> lk2(m_threadMutex);
148 
150  m_mainCanProceed = false;
151  m_masterCanProceed = true;
152  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: Signal master for EndRun";
153  m_notifyMasterCv.notify_one();
154  m_notifyMainCv.wait(lk2, [&]() { return m_mainCanProceed; });
155  lk2.unlock();
156  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread: finish EndRun";
157 }
158 
160  if (m_stopped) {
161  return;
162  }
163  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread::stopTread: stop main thread";
164 
165  // Release our instance of the shared master run manager, so that
166  // the G4 master thread can do the cleanup. Then notify the master
167  // thread, and join it.
168  std::unique_lock<std::mutex> lk2(m_threadMutex);
169  m_runManagerMaster.reset();
170  LogDebug("OscarMTMasterThread") << "Main thread: reseted shared_ptr";
171 
173  m_masterCanProceed = true;
174  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread::stopTread: notify";
175  m_notifyMasterCv.notify_one();
176  lk2.unlock();
177 
178  LogDebug("OscarMTMasterThread") << "Main thread: joining master thread";
179  m_masterThread.join();
180  edm::LogVerbatim("SimG4CoreApplication") << "OscarMTMasterThread::stopTread: main thread finished";
181  m_stopped = true;
182 }
OscarMTMasterThread::m_hasToken
bool m_hasToken
Definition: OscarMTMasterThread.h:75
OscarMTMasterThread::m_notifyMasterCv
std::condition_variable m_notifyMasterCv
Definition: OscarMTMasterThread.h:70
electrons_cff.bool
bool
Definition: electrons_cff.py:366
OscarMTMasterThread::m_masterThread
std::thread m_masterThread
Definition: OscarMTMasterThread.h:57
edm::errors::LogicError
Definition: EDMException.h:37
OscarMTMasterThread::m_firstRun
bool m_firstRun
Definition: OscarMTMasterThread.h:78
OscarMTMasterThread::OscarMTMasterThread
OscarMTMasterThread(const edm::ParameterSet &iConfig)
Definition: OscarMTMasterThread.cc:12
OscarMTMasterThread::m_DDD
edm::ESGetToken< DDCompactView, IdealGeometryRecord > m_DDD
Definition: OscarMTMasterThread.h:63
OscarMTMasterThread.h
OscarMTMasterThread::ThreadState::BeginRun
OscarMTMasterThread::endRun
void endRun() const
Definition: OscarMTMasterThread.cc:145
OscarMTMasterThread::m_PDT
edm::ESGetToken< HepPDT::ParticleDataTable, PDTRecord > m_PDT
Definition: OscarMTMasterThread.h:65
EDMException.h
OscarMTMasterThread::ThreadState
ThreadState
Definition: OscarMTMasterThread.h:52
OscarMTMasterThread::ThreadState::EndRun
OscarMTMasterThread::m_masterThreadState
ThreadState m_masterThreadState
Definition: OscarMTMasterThread.h:73
DDCompactView
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:81
OscarMTMasterThread::m_mainCanProceed
bool m_mainCanProceed
Definition: OscarMTMasterThread.h:77
OscarMTMasterThread::m_runManagerMaster
std::shared_ptr< RunManagerMT > m_runManagerMaster
Definition: OscarMTMasterThread.h:56
CustomUIsession.h
OscarMTMasterThread::stopThread
void stopThread()
Definition: OscarMTMasterThread.cc:159
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:233
edm::ParameterSet
Definition: ParameterSet.h:47
OscarMTMasterThread::m_protectMutex
std::mutex m_protectMutex
Definition: OscarMTMasterThread.h:68
RunManagerMT.h
OscarMTMasterThread::m_DD4Hep
edm::ESGetToken< cms::DDCompactView, IdealGeometryRecord > m_DD4Hep
Definition: OscarMTMasterThread.h:64
OscarMTMasterThread::~OscarMTMasterThread
~OscarMTMasterThread()
Definition: OscarMTMasterThread.cc:101
OscarMTMasterThread::m_stopped
bool m_stopped
Definition: OscarMTMasterThread.h:79
edm::EventSetup
Definition: EventSetup.h:58
OscarMTMasterThread::m_pDD4Hep
const cms::DDCompactView * m_pDD4Hep
Definition: OscarMTMasterThread.h:61
edm::EventSetup::getTransientHandle
ESTransientHandle< T > getTransientHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:166
edm::EventSetup::getData
bool getData(T &iHolder) const
Definition: EventSetup.h:127
OscarMTMasterThread::m_masterCanProceed
bool m_masterCanProceed
Definition: OscarMTMasterThread.h:76
OscarMTMasterThread::m_pGeoFromDD4hep
const bool m_pGeoFromDD4hep
Definition: OscarMTMasterThread.h:54
OscarMTMasterThread::m_pDDD
const DDCompactView * m_pDDD
Definition: OscarMTMasterThread.h:60
edm::LogVerbatim
Log< level::Info, true > LogVerbatim
Definition: MessageLogger.h:128
edm::Transition::BeginRun
Exception
Definition: hltDiff.cc:245
cms::DDCompactView
Definition: DDCompactView.h:31
OscarMTMasterThread::beginRun
void beginRun(const edm::EventSetup &iSetup) const
Definition: OscarMTMasterThread.cc:120
OscarMTMasterThread::m_pTable
const HepPDT::ParticleDataTable * m_pTable
Definition: OscarMTMasterThread.h:62
ConsumesCollector.h
OscarMTMasterThread::m_threadMutex
std::mutex m_threadMutex
Definition: OscarMTMasterThread.h:69
PDTRecord
Definition: PDTRecord.h:14
ParticleDataTable
HepPDT::ParticleDataTable ParticleDataTable
Definition: ParticleDataTable.h:8
edm::ConsumesCollector
Definition: ConsumesCollector.h:45
OscarMTMasterThread::m_notifyMainCv
std::condition_variable m_notifyMainCv
Definition: OscarMTMasterThread.h:71
OscarMTMasterThread::ThreadState::Destruct
IdealGeometryRecord
Definition: IdealGeometryRecord.h:25
OscarMTMasterThread::callConsumes
void callConsumes(edm::ConsumesCollector &&iC) const
Definition: OscarMTMasterThread.cc:107