forked from OSchip/llvm-project
[clangd] Use llvm::set_thread_priority in background-index
Reviewers: gribozavr Subscribers: krytarowski, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jfb, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D60865 llvm-svn: 358664
This commit is contained in:
parent
196a440411
commit
f8537b3c69
|
@ -113,33 +113,5 @@ void wait(std::unique_lock<std::mutex> &Lock, std::condition_variable &CV,
|
|||
CV.wait_until(Lock, D.time());
|
||||
}
|
||||
|
||||
static std::atomic<bool> AvoidThreadStarvation = {false};
|
||||
|
||||
void setCurrentThreadPriority(ThreadPriority Priority) {
|
||||
// Some *really* old glibcs are missing SCHED_IDLE.
|
||||
#if defined(__linux__) && defined(SCHED_IDLE)
|
||||
sched_param priority;
|
||||
priority.sched_priority = 0;
|
||||
pthread_setschedparam(
|
||||
pthread_self(),
|
||||
Priority == ThreadPriority::Low && !AvoidThreadStarvation ? SCHED_IDLE
|
||||
: SCHED_OTHER,
|
||||
&priority);
|
||||
#elif defined(__APPLE__)
|
||||
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpriority.2.html
|
||||
setpriority(PRIO_DARWIN_THREAD, 0,
|
||||
Priority == ThreadPriority::Low && !AvoidThreadStarvation
|
||||
? PRIO_DARWIN_BG
|
||||
: 0);
|
||||
#elif defined(_WIN32)
|
||||
SetThreadPriority(GetCurrentThread(),
|
||||
Priority == ThreadPriority::Low && !AvoidThreadStarvation
|
||||
? THREAD_MODE_BACKGROUND_BEGIN
|
||||
: THREAD_MODE_BACKGROUND_END);
|
||||
#endif
|
||||
}
|
||||
|
||||
void preventThreadStarvationInTests() { AvoidThreadStarvation = true; }
|
||||
|
||||
} // namespace clangd
|
||||
} // namespace clang
|
||||
|
|
|
@ -117,16 +117,6 @@ private:
|
|||
std::size_t InFlightTasks = 0;
|
||||
};
|
||||
|
||||
enum class ThreadPriority {
|
||||
Low = 0,
|
||||
Normal = 1,
|
||||
};
|
||||
void setCurrentThreadPriority(ThreadPriority Priority);
|
||||
// Avoid the use of scheduler policies that may starve low-priority threads.
|
||||
// This prevents tests from timing out on loaded systems.
|
||||
// Affects subsequent setThreadPriority() calls.
|
||||
void preventThreadStarvationInTests();
|
||||
|
||||
} // namespace clangd
|
||||
} // namespace clang
|
||||
#endif
|
||||
|
|
|
@ -26,7 +26,9 @@
|
|||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/SHA1.h"
|
||||
#include "llvm/Support/Threading.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
|
@ -38,6 +40,9 @@
|
|||
namespace clang {
|
||||
namespace clangd {
|
||||
namespace {
|
||||
|
||||
static std::atomic<bool> PreventStarvation = {false};
|
||||
|
||||
// Resolves URI to file paths with cache.
|
||||
class URIToFileCache {
|
||||
public:
|
||||
|
@ -172,7 +177,7 @@ void BackgroundIndex::run() {
|
|||
WithContext Background(BackgroundContext.clone());
|
||||
while (true) {
|
||||
llvm::Optional<Task> Task;
|
||||
ThreadPriority Priority;
|
||||
llvm::ThreadPriority Priority;
|
||||
{
|
||||
std::unique_lock<std::mutex> Lock(QueueMu);
|
||||
QueueCV.wait(Lock, [&] { return ShouldStop || !Queue.empty(); });
|
||||
|
@ -186,11 +191,11 @@ void BackgroundIndex::run() {
|
|||
Queue.pop_front();
|
||||
}
|
||||
|
||||
if (Priority != ThreadPriority::Normal)
|
||||
setCurrentThreadPriority(Priority);
|
||||
if (Priority != llvm::ThreadPriority::Default && !PreventStarvation.load())
|
||||
llvm::set_thread_priority(Priority);
|
||||
(*Task)();
|
||||
if (Priority != ThreadPriority::Normal)
|
||||
setCurrentThreadPriority(ThreadPriority::Normal);
|
||||
if (Priority != llvm::ThreadPriority::Default)
|
||||
llvm::set_thread_priority(llvm::ThreadPriority::Default);
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> Lock(QueueMu);
|
||||
|
@ -223,7 +228,7 @@ void BackgroundIndex::enqueue(const std::vector<std::string> &ChangedFiles) {
|
|||
for (auto &Elem : NeedsReIndexing)
|
||||
enqueue(std::move(Elem.first), Elem.second);
|
||||
},
|
||||
ThreadPriority::Normal);
|
||||
llvm::ThreadPriority::Default);
|
||||
}
|
||||
|
||||
void BackgroundIndex::enqueue(tooling::CompileCommand Cmd,
|
||||
|
@ -238,10 +243,10 @@ void BackgroundIndex::enqueue(tooling::CompileCommand Cmd,
|
|||
std::move(Error));
|
||||
},
|
||||
std::move(Cmd)),
|
||||
ThreadPriority::Low);
|
||||
llvm::ThreadPriority::Background);
|
||||
}
|
||||
|
||||
void BackgroundIndex::enqueueTask(Task T, ThreadPriority Priority) {
|
||||
void BackgroundIndex::enqueueTask(Task T, llvm::ThreadPriority Priority) {
|
||||
{
|
||||
std::lock_guard<std::mutex> Lock(QueueMu);
|
||||
auto I = Queue.end();
|
||||
|
@ -249,9 +254,10 @@ void BackgroundIndex::enqueueTask(Task T, ThreadPriority Priority) {
|
|||
// Then we store low priority tasks. Normal priority tasks are pretty rare,
|
||||
// they should not grow beyond single-digit numbers, so it is OK to do
|
||||
// linear search and insert after that.
|
||||
if (Priority == ThreadPriority::Normal) {
|
||||
I = llvm::find_if(Queue, [](const std::pair<Task, ThreadPriority> &Elem) {
|
||||
return Elem.second == ThreadPriority::Low;
|
||||
if (Priority == llvm::ThreadPriority::Default) {
|
||||
I = llvm::find_if(
|
||||
Queue, [](const std::pair<Task, llvm::ThreadPriority> &Elem) {
|
||||
return Elem.second == llvm::ThreadPriority::Background;
|
||||
});
|
||||
}
|
||||
Queue.insert(I, {std::move(T), Priority});
|
||||
|
@ -611,5 +617,9 @@ BackgroundIndex::loadShards(std::vector<std::string> ChangedFiles) {
|
|||
return NeedsReIndexing;
|
||||
}
|
||||
|
||||
void BackgroundIndex::preventThreadStarvationInTests() {
|
||||
PreventStarvation.store(true);
|
||||
}
|
||||
|
||||
} // namespace clangd
|
||||
} // namespace clang
|
||||
|
|
|
@ -88,6 +88,10 @@ public:
|
|||
LLVM_NODISCARD bool
|
||||
blockUntilIdleForTest(llvm::Optional<double> TimeoutSeconds = 10);
|
||||
|
||||
// Disables thread priority lowering in background index to make sure it can
|
||||
// progress on loaded systems. Only affects tasks that run after the call.
|
||||
static void preventThreadStarvationInTests();
|
||||
|
||||
private:
|
||||
/// Given index results from a TU, only update symbols coming from files with
|
||||
/// different digests than \p DigestsSnapshot. Also stores new index
|
||||
|
@ -134,14 +138,14 @@ private:
|
|||
// queue management
|
||||
using Task = std::function<void()>;
|
||||
void run(); // Main loop executed by Thread. Runs tasks from Queue.
|
||||
void enqueueTask(Task T, ThreadPriority Prioirty);
|
||||
void enqueueTask(Task T, llvm::ThreadPriority Prioirty);
|
||||
void enqueueLocked(tooling::CompileCommand Cmd,
|
||||
BackgroundIndexStorage *IndexStorage);
|
||||
std::mutex QueueMu;
|
||||
unsigned NumActiveTasks = 0; // Only idle when queue is empty *and* no tasks.
|
||||
std::condition_variable QueueCV;
|
||||
bool ShouldStop = false;
|
||||
std::deque<std::pair<Task, ThreadPriority>> Queue;
|
||||
std::deque<std::pair<Task, llvm::ThreadPriority>> Queue;
|
||||
std::vector<std::thread> ThreadPool; // FIXME: Abstract this away.
|
||||
GlobalCompilationDatabase::CommandChanged::Subscription CommandsChanged;
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Protocol.h"
|
||||
#include "Trace.h"
|
||||
#include "Transport.h"
|
||||
#include "index/Background.h"
|
||||
#include "index/Serialization.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
|
@ -332,7 +333,8 @@ int main(int argc, char *argv[]) {
|
|||
InputStyle = JSONStreamStyle::Delimited;
|
||||
LogLevel = Logger::Verbose;
|
||||
PrettyPrint = true;
|
||||
preventThreadStarvationInTests(); // Ensure background index makes progress.
|
||||
// Ensure background index makes progress.
|
||||
BackgroundIndex::preventThreadStarvationInTests();
|
||||
}
|
||||
if (Test || EnableTestScheme) {
|
||||
static URISchemeRegistry::Add<TestScheme> X(
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
|
||||
class BackgroundIndexTest : public ::testing::Test {
|
||||
protected:
|
||||
BackgroundIndexTest() { preventThreadStarvationInTests(); }
|
||||
BackgroundIndexTest() { BackgroundIndex::preventThreadStarvationInTests(); }
|
||||
};
|
||||
|
||||
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile) {
|
||||
|
|
Loading…
Reference in New Issue