diff --git a/Sim/Simulation/ISimulation.cpp b/Sim/Simulation/ISimulation.cpp index 269141219da4ea8fa5693bf5ec437b6c44498808..e8752aeefa79efe5ebd2fe0dbcbfa8c7eacc9010 100644 --- a/Sim/Simulation/ISimulation.cpp +++ b/Sim/Simulation/ISimulation.cpp @@ -26,6 +26,7 @@ #include <gsl/gsl_errno.h> #include <iostream> #include <thread> +#include <mutex> namespace { @@ -223,32 +224,32 @@ void ISimulation::runSingleSimulation(const ReSample& re_sample, size_t batch_st throw std::runtime_error("Unexpected error in simulation:\n" + c->errorMessage()); } else { - // Create batch computations. - std::vector<std::unique_ptr<IComputation>> computations; + // Launch computation threads. + std::vector<std::unique_ptr<std::thread>> threads; + std::vector<std::string> failure_messages; + std::mutex mutex; for (size_t i_thread = 0; i_thread < n_threads; ++i_thread) { const size_t thread_start = batch_start + startIndex(n_threads, i_thread, batch_size); const size_t thread_size = batchSize(n_threads, i_thread, batch_size); if (thread_size == 0) break; - computations.emplace_back(createComputation(re_sample, thread_start, thread_size)); - } - - // Run computations in several threads. - std::vector<std::unique_ptr<std::thread>> threads; - for (const auto& c : computations) - threads.emplace_back(new std::thread([&c]() { + threads.emplace_back(new std::thread([&]() { + mutex.lock(); + const auto& c = createComputation(re_sample, thread_start, thread_size); + mutex.unlock(); c->compute(); // <---- here most work is done (threaded case)! + mutex.lock(); + if (!c->isCompleted()) + failure_messages.push_back(c->errorMessage()); + mutex.unlock(); })); + } // Wait for threads to complete. for (auto& thread : threads) thread->join(); // Check successful completion. - std::vector<std::string> failure_messages; - for (const auto& c : computations) - if (!c->isCompleted()) - failure_messages.push_back(c->errorMessage()); if (!failure_messages.empty()) throw std::runtime_error("Unexpected error in simulation thread(s):\n" + BaseUtils::String::join(failure_messages, " --- "));