Fix races and UBs

This commit is contained in:
Tomasz Sobczyk
2020-10-18 22:35:16 +02:00
committed by nodchip
parent 97fb9a89e4
commit fd229c0768
2 changed files with 21 additions and 18 deletions

View File

@@ -35,6 +35,7 @@ ThreadPool Threads; // Global object
Thread::Thread(size_t n) : idx(n), stdThread(&Thread::idle_loop, this) {
wait_for_search_finished();
wait_for_worker_finished();
}
@@ -80,10 +81,11 @@ void Thread::start_searching() {
cv.notify_one(); // Wake up the thread in idle_loop()
}
void Thread::execute_task(std::function<void(Thread&)> t)
void Thread::execute_with_worker(std::function<void(Thread&)> t)
{
std::lock_guard<std::mutex> lk(mutex);
task = std::move(t);
worker = std::move(t);
searching = true;
cv.notify_one(); // Wake up the thread in idle_loop()
}
@@ -98,10 +100,10 @@ void Thread::wait_for_search_finished() {
}
void Thread::wait_for_task_finished() {
void Thread::wait_for_worker_finished() {
std::unique_lock<std::mutex> lk(mutex);
cv.wait(lk, [&]{ return !task; });
cv.wait(lk, [&]{ return !searching; });
}
/// Thread::idle_loop() is where the thread is parked, blocked on the
@@ -121,18 +123,20 @@ void Thread::idle_loop() {
{
std::unique_lock<std::mutex> lk(mutex);
searching = false;
worker = nullptr;
cv.notify_one(); // Wake up anyone waiting for search finished
cv.wait(lk, [&]{ return searching || task; });
cv.wait(lk, [&]{ return searching; });
if (exit)
return;
auto wrk = std::move(worker);
lk.unlock();
if (task)
if (wrk)
{
task(*this);
task = nullptr;
wrk(*this);
}
else
{
@@ -183,11 +187,11 @@ void ThreadPool::clear() {
}
void ThreadPool::execute_parallel(std::function<void(Thread&)> task)
void ThreadPool::execute_with_workers(std::function<void(Thread&)> worker)
{
for(Thread* th : *this)
{
th->execute_task(task);
th->execute_with_worker(std::move(worker));
}
}
@@ -301,8 +305,8 @@ void ThreadPool::wait_for_search_finished() const {
}
void ThreadPool::wait_for_tasks_finished() const {
void ThreadPool::wait_for_workers_finished() const {
for (Thread* th : *this)
th->wait_for_task_finished();
th->wait_for_worker_finished();
}