Lower priority on build

This should prevent slowdown of the IDE (and the rest of the system) while
building with all the CPU cores.

Fixes: QTCREATORBUG-5155
Change-Id: Icaadc53958f2d8e918035463e3c9344c91235615
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Orgad Shaneh
2019-09-10 23:39:29 +03:00
committed by Orgad Shaneh
parent 057215eb10
commit e38361b5a8
8 changed files with 54 additions and 5 deletions

View File

@@ -45,6 +45,7 @@
const wchar_t szTitle[] = L"qtcctrlcstub"; const wchar_t szTitle[] = L"qtcctrlcstub";
const wchar_t szWindowClass[] = L"wcqtcctrlcstub"; const wchar_t szWindowClass[] = L"wcqtcctrlcstub";
const wchar_t szNice[] = L"-nice ";
UINT uiShutDownWindowMessage; UINT uiShutDownWindowMessage;
UINT uiInterruptMessage; UINT uiInterruptMessage;
HWND hwndMain = nullptr; HWND hwndMain = nullptr;
@@ -53,7 +54,7 @@ LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
BOOL WINAPI shutdownHandler(DWORD dwCtrlType); BOOL WINAPI shutdownHandler(DWORD dwCtrlType);
BOOL WINAPI interruptHandler(DWORD dwCtrlType); BOOL WINAPI interruptHandler(DWORD dwCtrlType);
bool isSpaceOrTab(const wchar_t c); bool isSpaceOrTab(const wchar_t c);
bool startProcess(wchar_t pCommandLine[]); bool startProcess(wchar_t pCommandLine[], bool lowerPriority);
int main(int argc, char **) int main(int argc, char **)
{ {
@@ -93,7 +94,14 @@ int main(int argc, char **)
++pos; ++pos;
} }
bool bSuccess = startProcess(strCommandLine + pos); const size_t niceLen = wcslen(szNice);
bool lowerPriority = !wcsncmp(strCommandLine + pos, szNice, niceLen);
if (lowerPriority) {
pos += niceLen - 1; // reach the space, then the following line skips all spaces.
while (isSpaceOrTab(strCommandLine[++pos]))
;
}
bool bSuccess = startProcess(strCommandLine + pos, lowerPriority);
free(strCommandLine); free(strCommandLine);
if (!bSuccess) if (!bSuccess)
@@ -166,7 +174,7 @@ DWORD WINAPI processWatcherThread(LPVOID lpParameter)
return 0; return 0;
} }
bool startProcess(wchar_t *pCommandLine) bool startProcess(wchar_t *pCommandLine, bool lowerPriority)
{ {
SECURITY_ATTRIBUTES sa = {0}; SECURITY_ATTRIBUTES sa = {0};
sa.nLength = sizeof(sa); sa.nLength = sizeof(sa);
@@ -176,7 +184,7 @@ bool startProcess(wchar_t *pCommandLine)
si.cb = sizeof(si); si.cb = sizeof(si);
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
DWORD dwCreationFlags = 0; DWORD dwCreationFlags = lowerPriority ? BELOW_NORMAL_PRIORITY_CLASS : 0;
BOOL bSuccess = CreateProcess(NULL, pCommandLine, &sa, &sa, TRUE, dwCreationFlags, NULL, NULL, &si, &pi); BOOL bSuccess = CreateProcess(NULL, pCommandLine, &sa, &sa, TRUE, dwCreationFlags, NULL, NULL, &si, &pi);
if (!bSuccess) { if (!bSuccess) {
fwprintf(stderr, L"qtcreator_ctrlc_stub: Command line failed: %s\n", pCommandLine); fwprintf(stderr, L"qtcreator_ctrlc_stub: Command line failed: %s\n", pCommandLine);

View File

@@ -37,6 +37,9 @@
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <qt_windows.h> #include <qt_windows.h>
#else
#include <errno.h>
#include <unistd.h>
#endif #endif
@@ -712,9 +715,17 @@ void QtcProcess::start()
if (osType == OsTypeWindows) { if (osType == OsTypeWindows) {
QString args; QString args;
if (m_useCtrlCStub) { if (m_useCtrlCStub) {
args = QtcProcess::quoteArg(QDir::toNativeSeparators(command)); if (m_lowPriority)
addArg(&args, "-nice");
addArg(&args, QDir::toNativeSeparators(command));
command = QCoreApplication::applicationDirPath() command = QCoreApplication::applicationDirPath()
+ QLatin1String("/qtcreator_ctrlc_stub.exe"); + QLatin1String("/qtcreator_ctrlc_stub.exe");
} else if (m_lowPriority) {
#ifdef Q_OS_WIN
setCreateProcessArgumentsModifier([](CreateProcessArguments *args) {
args->flags |= BELOW_NORMAL_PRIORITY_CLASS;
});
#endif
} }
QtcProcess::addArgs(&args, arguments.toWindowsArgs()); QtcProcess::addArgs(&args, arguments.toWindowsArgs());
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
@@ -1208,6 +1219,19 @@ QString QtcProcess::expandMacros(const QString &str, AbstractMacroExpander *mx,
return ret; return ret;
} }
void QtcProcess::setupChildProcess()
{
#if defined Q_OS_UNIX
// nice value range is -20 to +19 where -20 is highest, 0 default and +19 is lowest
if (m_lowPriority) {
errno = 0;
if (::nice(5) == -1 && errno != 0)
qWarning("Failed to set nice value. Error: %d", errno);
}
#endif
QProcess::setupChildProcess();
}
bool QtcProcess::ArgIterator::next() bool QtcProcess::ArgIterator::next()
{ {
// We delay the setting of m_prev so we can still delete the last argument // We delay the setting of m_prev so we can still delete the last argument

View File

@@ -45,6 +45,7 @@ public:
void start(); void start();
void terminate(); void terminate();
void interrupt(); void interrupt();
void setLowPriority() { m_lowPriority = true; }
class QTCREATOR_UTILS_EXPORT Arguments class QTCREATOR_UTILS_EXPORT Arguments
{ {
@@ -141,10 +142,13 @@ public:
}; };
private: private:
void setupChildProcess() override;
CommandLine m_commandLine; CommandLine m_commandLine;
Environment m_environment; Environment m_environment;
bool m_haveEnv = false; bool m_haveEnv = false;
bool m_useCtrlCStub = false; bool m_useCtrlCStub = false;
bool m_lowPriority = false;
}; };
} // namespace Utils } // namespace Utils

View File

@@ -87,6 +87,8 @@ CMakeBuildStep::CMakeBuildStep(BuildStepList *bsl) :
if (m_buildTarget.isEmpty()) if (m_buildTarget.isEmpty())
setBuildTarget(defaultBuildTarget()); setBuildTarget(defaultBuildTarget());
setLowPriority();
connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged); connect(target(), &Target::kitChanged, this, &CMakeBuildStep::cmakeCommandChanged);
connect(project(), &Project::parsingFinished, connect(project(), &Project::parsingFinished,
this, &CMakeBuildStep::handleBuildTargetChanges); this, &CMakeBuildStep::handleBuildTargetChanges);

View File

@@ -109,6 +109,7 @@ public:
QByteArray deferredText; QByteArray deferredText;
bool m_ignoreReturnValue = false; bool m_ignoreReturnValue = false;
bool m_skipFlush = false; bool m_skipFlush = false;
bool m_lowPriority = false;
void readData(void (AbstractProcessStep::*func)(const QString &), bool isUtf8 = false); void readData(void (AbstractProcessStep::*func)(const QString &), bool isUtf8 = false);
void processLine(const QByteArray &data, void processLine(const QByteArray &data,
@@ -227,6 +228,8 @@ void AbstractProcessStep::doRun()
d->m_process->setWorkingDirectory(wd.absolutePath()); d->m_process->setWorkingDirectory(wd.absolutePath());
d->m_process->setEnvironment(d->m_param.environment()); d->m_process->setEnvironment(d->m_param.environment());
d->m_process->setCommand(effectiveCommand); d->m_process->setCommand(effectiveCommand);
if (d->m_lowPriority)
d->m_process->setLowPriority();
connect(d->m_process.get(), &QProcess::readyReadStandardOutput, connect(d->m_process.get(), &QProcess::readyReadStandardOutput,
this, &AbstractProcessStep::processReadyReadStdOutput); this, &AbstractProcessStep::processReadyReadStdOutput);
@@ -246,6 +249,11 @@ void AbstractProcessStep::doRun()
processStarted(); processStarted();
} }
void AbstractProcessStep::setLowPriority()
{
d->m_lowPriority = true;
}
void AbstractProcessStep::doCancel() void AbstractProcessStep::doCancel()
{ {
Core::Reaper::reap(d->m_process.release()); Core::Reaper::reap(d->m_process.release());

View File

@@ -57,6 +57,7 @@ protected:
~AbstractProcessStep() override; ~AbstractProcessStep() override;
bool init() override; bool init() override;
void doRun() override; void doRun() override;
void setLowPriority();
virtual void finish(bool success); virtual void finish(bool success);
virtual void processStarted(); virtual void processStarted();

View File

@@ -65,6 +65,7 @@ MakeStep::MakeStep(BuildStepList *parent, Core::Id id)
m_userJobCount(defaultJobCount()) m_userJobCount(defaultJobCount())
{ {
setDefaultDisplayName(defaultDisplayName()); setDefaultDisplayName(defaultDisplayName());
setLowPriority();
} }
void MakeStep::setBuildTarget(const QString &buildTarget) void MakeStep::setBuildTarget(const QString &buildTarget)

View File

@@ -76,6 +76,7 @@ QMakeStep::QMakeStep(BuildStepList *bsl) : AbstractProcessStep(bsl, Constants::Q
{ {
//: QMakeStep default display name //: QMakeStep default display name
setDefaultDisplayName(tr("qmake")); setDefaultDisplayName(tr("qmake"));
setLowPriority();
} }
QmakeBuildConfiguration *QMakeStep::qmakeBuildConfiguration() const QmakeBuildConfiguration *QMakeStep::qmakeBuildConfiguration() const