mirror of
https://github.com/intel/llvm.git
synced 2026-01-14 11:57:39 +08:00
Introduces the Task and TaskDispatcher interfaces (TaskDispatcher.h), ThreadPoolTaskDispatcher implementation (ThreadPoolTaskDispatch.h), and updates Session to include a TaskDispatcher instance that can be used to run tasks. TaskDispatcher's introduction is motivated by the need to handle calls to JIT'd code initiated from the controller process: Incoming calls will be wrapped in Tasks and dispatched. Session shutdown will wait on TaskDispatcher shutdown, ensuring that all Tasks are run or destroyed prior to the Session being destroyed.
71 lines
1.8 KiB
C++
71 lines
1.8 KiB
C++
//===- ThreadPoolTaskDispatch.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/ThreadPoolTaskDispatch.h
|
|
// header.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "orc-rt/ThreadPoolTaskDispatcher.h"
|
|
|
|
#include <cassert>
|
|
|
|
namespace orc_rt {
|
|
|
|
ThreadPoolTaskDispatcher::~ThreadPoolTaskDispatcher() {
|
|
assert(!AcceptingTasks && "shutdown was not run");
|
|
}
|
|
|
|
ThreadPoolTaskDispatcher::ThreadPoolTaskDispatcher(size_t NumThreads) {
|
|
Threads.reserve(NumThreads);
|
|
for (size_t I = 0; I < NumThreads; ++I)
|
|
Threads.emplace_back([this]() { taskLoop(); });
|
|
}
|
|
|
|
void ThreadPoolTaskDispatcher::dispatch(std::unique_ptr<Task> T) {
|
|
{
|
|
std::scoped_lock<std::mutex> Lock(M);
|
|
if (!AcceptingTasks)
|
|
return;
|
|
PendingTasks.push_back(std::move(T));
|
|
}
|
|
CV.notify_one();
|
|
}
|
|
|
|
void ThreadPoolTaskDispatcher::shutdown() {
|
|
{
|
|
std::scoped_lock<std::mutex> Lock(M);
|
|
assert(AcceptingTasks && "ThreadPoolTaskDispatcher already shut down?");
|
|
AcceptingTasks = false;
|
|
}
|
|
CV.notify_all();
|
|
for (auto &Thread : Threads)
|
|
Thread.join();
|
|
}
|
|
|
|
void ThreadPoolTaskDispatcher::taskLoop() {
|
|
while (true) {
|
|
std::unique_ptr<Task> T;
|
|
{
|
|
std::unique_lock<std::mutex> Lock(M);
|
|
CV.wait(Lock,
|
|
[this]() { return !PendingTasks.empty() || !AcceptingTasks; });
|
|
|
|
if (!AcceptingTasks && PendingTasks.empty())
|
|
return;
|
|
|
|
T = std::move(PendingTasks.back());
|
|
PendingTasks.pop_back();
|
|
}
|
|
|
|
T->run();
|
|
}
|
|
}
|
|
|
|
} // namespace orc_rt
|