blob: 43e53d1574bc6b1db7e6d90d3712eb40aa380e68 [file] [edit]
//===- ThreadPoolRunner.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Contains the implementation of APIs in the orc-rt/ThreadPoolRunner.h
// header.
//
//===----------------------------------------------------------------------===//
#include "orc-rt/ThreadPoolRunner.h"
#include <cassert>
namespace orc_rt {
ThreadPoolRunner::ThreadPoolRunner(size_t NumThreads) {
Workers.reserve(NumThreads);
for (size_t I = 0; I < NumThreads; ++I)
Workers.emplace_back([this]() { workerLoop(); });
}
ThreadPoolRunner::~ThreadPoolRunner() {
{
std::scoped_lock<std::mutex> Lock(M);
Stop = true;
}
CV.notify_all();
for (auto &Worker : Workers)
Worker.join();
}
void ThreadPoolRunner::operator()(move_only_function<void()> Task) {
{
std::scoped_lock<std::mutex> Lock(M);
assert(!Stop &&
"operator() called on ThreadPoolRunner after destruction begun");
Pending.push_back(std::move(Task));
}
CV.notify_one();
}
void ThreadPoolRunner::workerLoop() {
while (true) {
move_only_function<void()> Call;
{
std::unique_lock<std::mutex> Lock(M);
CV.wait(Lock, [this]() { return !Pending.empty() || Stop; });
if (Pending.empty() && Stop)
return;
Call = std::move(Pending.back());
Pending.pop_back();
}
Call();
}
}
} // namespace orc_rt