From 3693f5941ab6ecefd173c94c6be2ae56a51acdf7 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Tue, 6 Feb 2018 19:22:40 +0000 Subject: Revert "[clangd] The new threading implementation" (r324356) And the follow-up changes r324361 and r324363. These changes seem to break two buildbots: - http://lab.llvm.org:8011/builders/clang-atom-d525-fedora-rel/builds/14091 - http://lab.llvm.org:8011/builders/clang-x86_64-linux-selfhost-modules-2/builds/16001 We will need to investigate what went wrong and resubmit the changes afterwards. llvm-svn: 324386 --- clang-tools-extra/clangd/Threading.cpp | 96 +++++++++++++++++----------------- 1 file changed, 48 insertions(+), 48 deletions(-) (limited to 'clang-tools-extra/clangd/Threading.cpp') diff --git a/clang-tools-extra/clangd/Threading.cpp b/clang-tools-extra/clangd/Threading.cpp index b067758a16a..3c0c74bb803 100644 --- a/clang-tools-extra/clangd/Threading.cpp +++ b/clang-tools-extra/clangd/Threading.cpp @@ -1,63 +1,63 @@ #include "Threading.h" -#include "llvm/ADT/ScopeExit.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Threading.h" -#include namespace clang { namespace clangd { +ThreadPool::ThreadPool(unsigned AsyncThreadsCount) + : RunSynchronously(AsyncThreadsCount == 0) { + if (RunSynchronously) { + // Don't start the worker thread if we're running synchronously + return; + } -CancellationFlag::CancellationFlag() - : WasCancelled(std::make_shared>(false)) {} - -Semaphore::Semaphore(std::size_t MaxLocks) : FreeSlots(MaxLocks) {} - -void Semaphore::lock() { - std::unique_lock Lock(Mutex); - SlotsChanged.wait(Lock, [&]() { return FreeSlots > 0; }); - --FreeSlots; -} - -void Semaphore::unlock() { - std::unique_lock Lock(Mutex); - ++FreeSlots; - Lock.unlock(); - - SlotsChanged.notify_one(); + Workers.reserve(AsyncThreadsCount); + for (unsigned I = 0; I < AsyncThreadsCount; ++I) { + Workers.push_back(std::thread([this, I]() { + llvm::set_thread_name(llvm::formatv("scheduler/{0}", I)); + while (true) { + UniqueFunction Request; + Context Ctx; + + // Pick request from the queue + { + std::unique_lock Lock(Mutex); + // Wait for more requests. + RequestCV.wait(Lock, + [this] { return !RequestQueue.empty() || Done; }); + if (RequestQueue.empty()) { + assert(Done); + return; + } + + // We process requests starting from the front of the queue. Users of + // ThreadPool have a way to prioritise their requests by putting + // them to the either side of the queue (using either addToEnd or + // addToFront). + std::tie(Request, Ctx) = std::move(RequestQueue.front()); + RequestQueue.pop_front(); + } // unlock Mutex + + WithContext WithCtx(std::move(Ctx)); + Request(); + } + })); + } } -AsyncTaskRunner::~AsyncTaskRunner() { waitForAll(); } - -void AsyncTaskRunner::waitForAll() { - std::unique_lock Lock(Mutex); - TasksReachedZero.wait(Lock, [&]() { return InFlightTasks == 0; }); -} +ThreadPool::~ThreadPool() { + if (RunSynchronously) + return; // no worker thread is running in that case -void AsyncTaskRunner::runAsync(UniqueFunction Action) { { - std::unique_lock Lock(Mutex); - ++InFlightTasks; - } - - auto CleanupTask = llvm::make_scope_exit([this]() { std::lock_guard Lock(Mutex); - int NewTasksCnt = --InFlightTasks; - if (NewTasksCnt == 0) { - // Note: we can't unlock here because we don't want the object to be - // destroyed before we notify. - TasksReachedZero.notify_one(); - } - }); - - std::thread( - [](decltype(Action) Action, decltype(CleanupTask)) { - Action(); - // Make sure function stored by Action is destroyed before CleanupTask - // is run. - Action = nullptr; - }, - std::move(Action), std::move(CleanupTask)) - .detach(); + // Wake up the worker thread + Done = true; + } // unlock Mutex + RequestCV.notify_all(); + + for (auto &Worker : Workers) + Worker.join(); } } // namespace clangd } // namespace clang -- cgit v1.2.1