Fixed a possible deadlock:

The thread counter should be modified under a mutex, atomic is not enough here
This commit is contained in:
Lukas Matena 2021-10-18 16:24:13 +02:00
parent d3c38fc603
commit c12eff19d8

View file

@ -208,7 +208,7 @@ void name_tbb_thread_pool_threads_set_locale()
nthreads = 1; nthreads = 1;
#endif #endif
std::atomic<size_t> nthreads_running(0); size_t nthreads_running(0);
std::condition_variable cv; std::condition_variable cv;
std::mutex cv_m; std::mutex cv_m;
auto master_thread_id = std::this_thread::get_id(); auto master_thread_id = std::this_thread::get_id();
@ -216,13 +216,13 @@ void name_tbb_thread_pool_threads_set_locale()
tbb::blocked_range<size_t>(0, nthreads, 1), tbb::blocked_range<size_t>(0, nthreads, 1),
[&nthreads_running, nthreads, &master_thread_id, &cv, &cv_m](const tbb::blocked_range<size_t> &range) { [&nthreads_running, nthreads, &master_thread_id, &cv, &cv_m](const tbb::blocked_range<size_t> &range) {
assert(range.begin() + 1 == range.end()); assert(range.begin() + 1 == range.end());
if (nthreads_running.fetch_add(1) + 1 == nthreads) { if (std::unique_lock<std::mutex> lk(cv_m); ++nthreads_running == nthreads) {
lk.unlock();
// All threads are spinning. // All threads are spinning.
// Wake them up. // Wake them up.
cv.notify_all(); cv.notify_all();
} else { } else {
// Wait for the last thread to wake the others. // Wait for the last thread to wake the others.
std::unique_lock<std::mutex> lk(cv_m);
cv.wait(lk, [&nthreads_running, nthreads]{return nthreads_running == nthreads;}); cv.wait(lk, [&nthreads_running, nthreads]{return nthreads_running == nthreads;});
} }
auto thread_id = std::this_thread::get_id(); auto thread_id = std::this_thread::get_id();