forked from qt-creator/qt-creator
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:
committed by
Orgad Shaneh
parent
057215eb10
commit
e38361b5a8
@@ -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);
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
@@ -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());
|
||||||
|
@@ -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();
|
||||||
|
@@ -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)
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user