Clangd: Let users limit the worker thread count

This is particularly interesting for indexing, where users might prefer
a slower-building index with less CPU load.

Change-Id: Id44c58e9041df2857cd0772e71345673b14623f3
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2021-06-25 18:16:08 +02:00
parent 876cd8e975
commit 56cddf38b3
4 changed files with 28 additions and 3 deletions

View File

@@ -387,6 +387,8 @@ static BaseClientInterface *clientInterface(const Utils::FilePath &jsonDbDir)
indexingOption += "=0"; indexingOption += "=0";
Utils::CommandLine cmd{CppTools::ClangdSettings::clangdFilePath(), Utils::CommandLine cmd{CppTools::ClangdSettings::clangdFilePath(),
{indexingOption, "--limit-results=0"}}; {indexingOption, "--limit-results=0"}};
if (CppTools::ClangdSettings::workerThreadLimit() != 0)
cmd.addArg("-j=" + QString::number(CppTools::ClangdSettings::workerThreadLimit()));
if (!jsonDbDir.isEmpty()) if (!jsonDbDir.isEmpty())
cmd.addArg("--compile-commands-dir=" + jsonDbDir.toString()); cmd.addArg("--compile-commands-dir=" + jsonDbDir.toString());
if (clangdLog().isDebugEnabled()) if (clangdLog().isDebugEnabled())

View File

@@ -66,6 +66,7 @@ static QString indexerFileSizeLimitKey()
static QString useClangdKey() { return QLatin1String("UseClangd"); } static QString useClangdKey() { return QLatin1String("UseClangd"); }
static QString clangdPathKey() { return QLatin1String("ClangdPath"); } static QString clangdPathKey() { return QLatin1String("ClangdPath"); }
static QString clangdIndexingKey() { return QLatin1String("ClangdIndexing"); } static QString clangdIndexingKey() { return QLatin1String("ClangdIndexing"); }
static QString clangdThreadLimitKey() { return QLatin1String("ClangdThreadLimit"); }
static FilePath g_defaultClangdFilePath; static FilePath g_defaultClangdFilePath;
static FilePath fallbackClangdFilePath() static FilePath fallbackClangdFilePath()
@@ -303,6 +304,7 @@ static bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Dat
{ {
return s1.useClangd == s2.useClangd return s1.useClangd == s2.useClangd
&& s1.executableFilePath == s2.executableFilePath && s1.executableFilePath == s2.executableFilePath
&& s1.workerThreadLimit == s2.workerThreadLimit
&& s1.enableIndexing == s2.enableIndexing; && s1.enableIndexing == s2.enableIndexing;
} }
static bool operator!=(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2) static bool operator!=(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)
@@ -342,6 +344,7 @@ void ClangdSettings::loadSettings()
m_data.useClangd = s->value(useClangdKey(), false).toBool(); m_data.useClangd = s->value(useClangdKey(), false).toBool();
m_data.executableFilePath = FilePath::fromString(s->value(clangdPathKey()).toString()); m_data.executableFilePath = FilePath::fromString(s->value(clangdPathKey()).toString());
m_data.enableIndexing = s->value(clangdIndexingKey(), true).toBool(); m_data.enableIndexing = s->value(clangdIndexingKey(), true).toBool();
m_data.workerThreadLimit = s->value(clangdThreadLimitKey(), 0).toInt();
} }
void ClangdSettings::saveSettings() void ClangdSettings::saveSettings()
@@ -350,6 +353,7 @@ void ClangdSettings::saveSettings()
s->setValue(useClangdKey(), useClangd()); s->setValue(useClangdKey(), useClangd());
s->setValue(clangdPathKey(), m_data.executableFilePath.toString()); s->setValue(clangdPathKey(), m_data.executableFilePath.toString());
s->setValue(clangdIndexingKey(), m_data.enableIndexing); s->setValue(clangdIndexingKey(), m_data.enableIndexing);
s->setValue(clangdThreadLimitKey(), m_data.workerThreadLimit);
} }
#ifdef WITH_TESTS #ifdef WITH_TESTS

View File

@@ -102,9 +102,10 @@ public:
class Data class Data
{ {
public: public:
Utils::FilePath executableFilePath;
int workerThreadLimit = 0;
bool useClangd = false; bool useClangd = false;
bool enableIndexing = true; bool enableIndexing = true;
Utils::FilePath executableFilePath;
}; };
static bool useClangd() { return instance().m_data.useClangd; } static bool useClangd() { return instance().m_data.useClangd; }
@@ -112,6 +113,7 @@ public:
static void setDefaultClangdPath(const Utils::FilePath &filePath); static void setDefaultClangdPath(const Utils::FilePath &filePath);
static Utils::FilePath clangdFilePath(); static Utils::FilePath clangdFilePath();
static bool indexingEnabled() { return instance().m_data.enableIndexing; } static bool indexingEnabled() { return instance().m_data.enableIndexing; }
static int workerThreadLimit() { return instance().m_data.workerThreadLimit; }
static void setData(const Data &data); static void setData(const Data &data);
static Data data() { return instance().m_data; } static Data data() { return instance().m_data; }

View File

@@ -36,6 +36,7 @@
#include <utils/pathchooser.h> #include <utils/pathchooser.h>
#include <QFormLayout> #include <QFormLayout>
#include <QSpinBox>
#include <QTextStream> #include <QTextStream>
namespace CppTools { namespace CppTools {
@@ -210,6 +211,10 @@ public:
"If background indexing is enabled, global symbol searches will yield\n" "If background indexing is enabled, global symbol searches will yield\n"
"more accurate results, at the cost of additional CPU load when\n" "more accurate results, at the cost of additional CPU load when\n"
"the project is first opened.")); "the project is first opened."));
m_threadLimitCheckBox.setText(tr("Set worker thread count limit"));
m_threadLimitCheckBox.setChecked(ClangdSettings::workerThreadLimit() != 0);
m_threadLimitSpinBox.setMinimum(1);
m_threadLimitSpinBox.setValue(ClangdSettings::workerThreadLimit());
const auto layout = new QVBoxLayout(this); const auto layout = new QVBoxLayout(this);
layout->addWidget(&m_useClangdCheckBox); layout->addWidget(&m_useClangdCheckBox);
@@ -218,6 +223,10 @@ public:
formLayout->addRow(chooserLabel, &m_clangdChooser); formLayout->addRow(chooserLabel, &m_clangdChooser);
const auto indexingLabel = new QLabel(tr("Enable background indexing:")); const auto indexingLabel = new QLabel(tr("Enable background indexing:"));
formLayout->addRow(indexingLabel, &m_indexingCheckBox); formLayout->addRow(indexingLabel, &m_indexingCheckBox);
const auto threadLimitLayout = new QHBoxLayout;
threadLimitLayout->addWidget(&m_threadLimitSpinBox);
threadLimitLayout->addStretch(1);
formLayout->addRow(&m_threadLimitCheckBox, threadLimitLayout);
layout->addLayout(formLayout); layout->addLayout(formLayout);
layout->addStretch(1); layout->addStretch(1);
@@ -226,9 +235,15 @@ public:
m_clangdChooser.setEnabled(checked); m_clangdChooser.setEnabled(checked);
indexingLabel->setEnabled(checked); indexingLabel->setEnabled(checked);
m_indexingCheckBox.setEnabled(checked); m_indexingCheckBox.setEnabled(checked);
m_threadLimitCheckBox.setEnabled(checked);
m_threadLimitSpinBox.setEnabled(checked && m_threadLimitCheckBox.isChecked());
}; };
connect(&m_useClangdCheckBox, &QCheckBox::toggled, toggleEnabled); connect(&m_useClangdCheckBox, &QCheckBox::toggled, toggleEnabled);
connect(&m_threadLimitCheckBox, &QCheckBox::toggled,
&m_threadLimitSpinBox, &QSpinBox::setEnabled);
toggleEnabled(m_useClangdCheckBox.isChecked()); toggleEnabled(m_useClangdCheckBox.isChecked());
m_threadLimitSpinBox.setEnabled(m_useClangdCheckBox.isChecked()
&& m_threadLimitCheckBox.isChecked());
} }
private: private:
@@ -238,11 +253,15 @@ private:
data.useClangd = m_useClangdCheckBox.isChecked(); data.useClangd = m_useClangdCheckBox.isChecked();
data.executableFilePath = m_clangdChooser.filePath(); data.executableFilePath = m_clangdChooser.filePath();
data.enableIndexing = m_indexingCheckBox.isChecked(); data.enableIndexing = m_indexingCheckBox.isChecked();
data.workerThreadLimit = m_threadLimitCheckBox.isChecked()
? m_threadLimitSpinBox.value() : 0;
ClangdSettings::setData(data); ClangdSettings::setData(data);
} }
QCheckBox m_useClangdCheckBox; QCheckBox m_useClangdCheckBox;
QCheckBox m_indexingCheckBox; QCheckBox m_indexingCheckBox;
QCheckBox m_threadLimitCheckBox;
QSpinBox m_threadLimitSpinBox;
Utils::PathChooser m_clangdChooser; Utils::PathChooser m_clangdChooser;
}; };
@@ -254,7 +273,5 @@ ClangdSettingsPage::ClangdSettingsPage()
setWidgetCreator([] { return new ClangdSettingsWidget; }); setWidgetCreator([] { return new ClangdSettingsWidget; });
} }
} // Internal } // Internal
} // CppTools } // CppTools