SimG4Core
Application
src
OscarMTMasterThread.cc
Go to the documentation of this file.
1
#include <memory>
2
3
#include "
SimG4Core/Application/interface/OscarMTMasterThread.h
"
4
#include "
FWCore/Utilities/interface/EDMException.h
"
5
#include "
FWCore/Framework/interface/ConsumesCollector.h
"
6
7
#include "
SimG4Core/Application/interface/RunManagerMT.h
"
8
#include "
SimG4Core/Geometry/interface/CustomUIsession.h
"
9
10
#include "G4PhysicalVolumeStore.hh"
11
12
OscarMTMasterThread::OscarMTMasterThread
(
const
edm::ParameterSet
& iConfig)
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
);
56
if
(
m_masterThreadState
==
ThreadState::BeginRun
) {
57
// Initialize Geant4
58
edm::LogVerbatim
(
"OscarMTMasterThread"
) <<
"Master thread: Initializing Geant4"
;
59
m_runManagerMaster
->initG4(
m_pDDD
,
m_pDD4Hep
,
m_pTable
);
60
isG4Alive =
true
;
61
}
else
if
(
m_masterThreadState
==
ThreadState::EndRun
) {
62
// Stop Geant4
63
edm::LogVerbatim
(
"OscarMTMasterThread"
) <<
"Master thread: Stopping Geant4"
;
64
m_runManagerMaster
->stopG4();
65
isG4Alive =
false
;
66
}
else
if
(
m_masterThreadState
==
ThreadState::Destruct
) {
67
edm::LogVerbatim
(
"OscarMTMasterThread"
) <<
"Master thread: Breaking out of state loop"
;
68
if
(isG4Alive)
69
throw
edm::Exception
(
edm::errors::LogicError
)
70
<<
"Geant4 is still alive, master thread state must be set to EndRun before Destruct"
;
71
break
;
72
}
else
{
73
throw
edm::Exception
(
edm::errors::LogicError
)
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
101
OscarMTMasterThread::~OscarMTMasterThread
() {
102
if
(!
m_stopped
) {
103
stopThread
();
104
}
105
}
106
107
void
OscarMTMasterThread::callConsumes
(
edm::ConsumesCollector
&& iC)
const
{
108
if
(
m_hasToken
) {
109
return
;
110
}
111
if
(
m_pGeoFromDD4hep
) {
112
m_DD4Hep
= iC.esConsumes<
cms::DDCompactView
,
IdealGeometryRecord
,
edm::Transition::BeginRun
>();
113
}
else
{
114
m_DDD
= iC.esConsumes<
DDCompactView
,
IdealGeometryRecord
,
edm::Transition::BeginRun
>();
115
}
116
m_PDT
= iC.esConsumes<
HepPDT::ParticleDataTable
,
PDTRecord
,
edm::Transition::BeginRun
>();
117
m_hasToken
=
true
;
118
}
119
120
void
OscarMTMasterThread::beginRun
(
const
edm::EventSetup
& iSetup)
const
{
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
}
134
m_masterThreadState
=
ThreadState::BeginRun
;
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
145
void
OscarMTMasterThread::endRun
()
const
{
146
std::lock_guard<std::mutex> lk(
m_protectMutex
);
147
std::unique_lock<std::mutex> lk2(
m_threadMutex
);
148
149
m_masterThreadState
=
ThreadState::EndRun
;
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
159
void
OscarMTMasterThread::stopThread
() {
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
172
m_masterThreadState
=
ThreadState::Destruct
;
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
Generated for CMSSW Reference Manual by
1.8.16