llvm-project/clang-tools-extra/clangd/Threading.h

84 lines
2.7 KiB
C++

//===--- ThreadPool.h --------------------------------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_THREADING_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_THREADING_H
#include "Function.h"
#include <condition_variable>
#include <deque>
#include <mutex>
#include <thread>
#include <vector>
namespace clang {
namespace clangd {
/// A simple fixed-size thread pool implementation.
class ThreadPool {
public:
/// If \p AsyncThreadsCount is 0, requests added using addToFront and addToEnd
/// will be processed synchronously on the calling thread.
// Otherwise, \p AsyncThreadsCount threads will be created to schedule the
// requests.
ThreadPool(unsigned AsyncThreadsCount);
/// Destructor blocks until all requests are processed and worker threads are
/// terminated.
~ThreadPool();
/// Add a new request to run function \p F with args \p As to the start of the
/// queue. The request will be run on a separate thread.
template <class Func, class... Args>
void addToFront(Func &&F, Args &&... As) {
if (RunSynchronously) {
std::forward<Func>(F)(std::forward<Args>(As)...);
return;
}
{
std::lock_guard<std::mutex> Lock(Mutex);
RequestQueue.push_front(
BindWithForward(std::forward<Func>(F), std::forward<Args>(As)...));
}
RequestCV.notify_one();
}
/// Add a new request to run function \p F with args \p As to the end of the
/// queue. The request will be run on a separate thread.
template <class Func, class... Args> void addToEnd(Func &&F, Args &&... As) {
if (RunSynchronously) {
std::forward<Func>(F)(std::forward<Args>(As)...);
return;
}
{
std::lock_guard<std::mutex> Lock(Mutex);
RequestQueue.push_back(
BindWithForward(std::forward<Func>(F), std::forward<Args>(As)...));
}
RequestCV.notify_one();
}
private:
bool RunSynchronously;
mutable std::mutex Mutex;
/// We run some tasks on separate threads(parsing, CppFile cleanup).
/// These threads looks into RequestQueue to find requests to handle and
/// terminate when Done is set to true.
std::vector<std::thread> Workers;
/// Setting Done to true will make the worker threads terminate.
bool Done = false;
/// A queue of requests.
std::deque<UniqueFunction<void()>> RequestQueue;
/// Condition variable to wake up worker threads.
std::condition_variable RequestCV;
};
} // namespace clangd
} // namespace clang
#endif