| 122 | //============================================================================// |
| 123 | |
| 124 | void G4TaskRunManagerKernel::InitializeWorker() |
| 125 | { |
| 126 | if (context() && workerRM()) return; |
| 127 | |
| 128 | G4TaskRunManager* mrm = G4TaskRunManager::GetMasterRunManager(); |
| 129 | if (G4MTRunManager::GetMasterThreadId() == G4ThisThread::get_id()) { |
| 130 | G4TaskManager* taskManager = mrm->GetTaskManager(); |
| 131 | auto _fut = taskManager->async(InitializeWorker); |
| 132 | _fut->wait(); |
| 133 | return; |
| 134 | } |
| 135 | |
| 136 | //!!!!!!!!!!!!!!!!!!!!!!!!!! |
| 137 | //!!!!!! IMPORTANT !!!!!!!!! |
| 138 | //!!!!!!!!!!!!!!!!!!!!!!!!!! |
| 139 | // Here is not sequential anymore and G4UserWorkerThreadInitialization is |
| 140 | // a shared user initialization class |
| 141 | // This means this method cannot use data memebers of G4RunManagerKernel |
| 142 | // unless they are invariant ("read-only") and can be safely shared. |
| 143 | // All the rest that is not invariant should be incapsualted into |
| 144 | // the context (or, as for wThreadContext be G4ThreadLocal) |
| 145 | //!!!!!!!!!!!!!!!!!!!!!!!!!! |
| 146 | |
| 147 | G4Threading::WorkerThreadJoinsPool(); |
| 148 | context() = std::make_unique<G4WorkerThread>(); |
| 149 | |
| 150 | //============================ |
| 151 | // Step-0: Thread ID |
| 152 | //============================ |
| 153 | // Initliazie per-thread stream-output |
| 154 | // The following line is needed before we actually do IO initialization |
| 155 | // becasue the constructor of UI manager resets the IO destination. |
| 156 | context()->SetNumberThreads((G4int)mrm->GetThreadPool()->size()); |
| 157 | context()->SetThreadId(G4int(G4ThreadPool::get_this_thread_id() - 1)); |
| 158 | G4int thisID = context()->GetThreadId(); |
| 159 | G4Threading::G4SetThreadId(thisID); |
| 160 | G4UImanager::GetUIpointer()->SetUpForAThread(thisID); |
| 161 | |
| 162 | //============================ |
| 163 | // Optimization: optional |
| 164 | //============================ |
| 165 | // Enforce thread affinity if requested |
| 166 | context()->SetPinAffinity(mrm->GetPinAffinity()); |
| 167 | |
| 168 | //============================ |
| 169 | // Step-1: Random number engine |
| 170 | //============================ |
| 171 | // RNG Engine needs to be initialized by "cloning" the master one. |
| 172 | const CLHEP::HepRandomEngine* masterEngine = mrm->getMasterRandomEngine(); |
| 173 | mrm->GetUserWorkerThreadInitialization()->SetupRNGEngine(masterEngine); |
| 174 | |
| 175 | //============================ |
| 176 | // Step-2: Initialize worker thread |
| 177 | //============================ |
| 178 | if (mrm->GetUserWorkerInitialization() != nullptr) |
| 179 | mrm->GetUserWorkerInitialization()->WorkerInitialize(); |
| 180 | |
| 181 | if (mrm->GetUserActionInitialization() != nullptr) { |
nothing calls this directly
no test coverage detected