summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorArttu Tarkiainen <arttu.tarkiainen@qt.io>2022-04-04 15:18:27 +0300
committerArttu Tarkiainen <arttu.tarkiainen@qt.io>2022-04-21 14:24:31 +0000
commit99db65c70ab7cdc458e197440af8251cd48c8e89 (patch)
tree55fe59ac8f89f48343d430536df2eb48bb15dc1e /src
parent4b1af7d32b062f954a84616e28bb6296a28522b4 (diff)
Add option for specifying maximum concurrent unpack operations
For tracing issues with the multithreaded extraction and limiting the processor load from the installer. Task-number: QTIFW-2586 Change-Id: I5df0bf6be30b4ee5ef8470c407281e2a4318ed0c Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/libs/installer/commandlineparser.cpp7
-rw-r--r--src/libs/installer/concurrentoperationrunner.cpp22
-rw-r--r--src/libs/installer/concurrentoperationrunner.h3
-rw-r--r--src/libs/installer/constants.h2
-rw-r--r--src/libs/installer/packagemanagercore.cpp25
-rw-r--r--src/libs/installer/packagemanagercore.h3
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp2
-rw-r--r--src/sdk/sdkapp.h10
8 files changed, 71 insertions, 3 deletions
diff --git a/src/libs/installer/commandlineparser.cpp b/src/libs/installer/commandlineparser.cpp
index 67fc669e1..a04891303 100644
--- a/src/libs/installer/commandlineparser.cpp
+++ b/src/libs/installer/commandlineparser.cpp
@@ -225,6 +225,13 @@ CommandLineParser::CommandLineParser()
"parameter where SQUISH_PATH is pointing to your Squish installation folder: "
"<path_to_qt>/bin/qmake -r SQUISH_PATH=<pat_to_squish>"),
QLatin1String("port number")));
+ addOption(QCommandLineOption(QStringList()
+ << CommandLineOptions::scMaxConcurrentOperationsShort << CommandLineOptions::scMaxConcurrentOperationsLong,
+ QLatin1String("Specifies the maximum number of threads used to perform concurrent operations "
+ "in the unpacking phase of components. Set to a positive number, or 0 (default) "
+ "to let the application determine the ideal thread count from the amount of logical "
+ "processor cores in the system."),
+ QLatin1String("threads")));
// Deprecated options
QCommandLineOption deprecatedUpdater(CommandLineOptions::scDeprecatedUpdater);
diff --git a/src/libs/installer/concurrentoperationrunner.cpp b/src/libs/installer/concurrentoperationrunner.cpp
index 03012c593..c1a87ded2 100644
--- a/src/libs/installer/concurrentoperationrunner.cpp
+++ b/src/libs/installer/concurrentoperationrunner.cpp
@@ -42,8 +42,9 @@ using namespace QInstaller;
The class accepts an operation list of any registered operation type. It can be
used to execute the \c Backup, \c Perform, or \c Undo steps of the operations. The
- operations are run in the global thread pool, which by default limits the maximum
- number of threads to the ideal number of logical processor cores in the system.
+ operations are run in a separate thread pool of this class, which by default limits
+ the maximum number of threads to the ideal number of logical processor cores in the
+ system.
*/
/*!
@@ -67,6 +68,7 @@ ConcurrentOperationRunner::ConcurrentOperationRunner(QObject *parent)
, m_totalOperations(0)
, m_operations(nullptr)
, m_type(Operation::OperationType::Perform)
+ , m_threadPool(new QThreadPool(this))
{
}
@@ -81,6 +83,7 @@ ConcurrentOperationRunner::ConcurrentOperationRunner(OperationList *operations,
, m_totalOperations(0)
, m_operations(operations)
, m_type(type)
+ , m_threadPool(new QThreadPool(this))
{
m_totalOperations = m_operations->size();
}
@@ -112,6 +115,19 @@ void ConcurrentOperationRunner::setType(const Operation::OperationType type)
}
/*!
+ Sets the maximum \a count of threads used by the thread pool of this class.
+ A value of \c 0 sets the count automatically to ideal number of threads.
+*/
+void ConcurrentOperationRunner::setMaxThreadCount(int count)
+{
+ if (count == 0) {
+ m_threadPool->setMaxThreadCount(QThread::idealThreadCount());
+ return;
+ }
+ m_threadPool->setMaxThreadCount(count);
+}
+
+/*!
\internal
Runs \a operation in mode of \a type. Returns \c true on success, \c false otherwise.
@@ -148,7 +164,7 @@ QHash<Operation *, bool> ConcurrentOperationRunner::run()
connect(futureWatcher, &QFutureWatcher<bool>::finished,
this, &ConcurrentOperationRunner::onOperationfinished);
- futureWatcher->setFuture(QtConcurrent::run(&runOperation, operation, m_type));
+ futureWatcher->setFuture(QtConcurrent::run(m_threadPool, &runOperation, operation, m_type));
}
if (!m_operationWatchers.isEmpty()) {
diff --git a/src/libs/installer/concurrentoperationrunner.h b/src/libs/installer/concurrentoperationrunner.h
index a74010f3e..f30020a95 100644
--- a/src/libs/installer/concurrentoperationrunner.h
+++ b/src/libs/installer/concurrentoperationrunner.h
@@ -50,6 +50,7 @@ public:
void setOperations(OperationList *operations);
void setType(const Operation::OperationType type);
+ void setMaxThreadCount(int count);
QHash<Operation *, bool> run();
@@ -75,6 +76,8 @@ private:
OperationList *m_operations;
Operation::OperationType m_type;
+
+ QThreadPool *const m_threadPool;
};
} // namespace QInstaller
diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h
index 1b7807e22..af518a0f6 100644
--- a/src/libs/installer/constants.h
+++ b/src/libs/installer/constants.h
@@ -217,6 +217,8 @@ static const QLatin1String scStartClientShort("sc");
static const QLatin1String scStartClientLong("start-client");
static const QLatin1String scSquishPortShort("q");
static const QLatin1String scSquishPortLong("squish-port");
+static const QLatin1String scMaxConcurrentOperationsShort("mco");
+static const QLatin1String scMaxConcurrentOperationsLong("max-concurrent-operations");
// Deprecated options, provided only for backward compatibility
static const QLatin1String scDeprecatedUpdater("updater");
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 0cea20032..b6f79a92b 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -459,6 +459,7 @@ static bool sNoForceInstallation = false;
static bool sNoDefaultInstallation = false;
static bool sVirtualComponentsVisible = false;
static bool sCreateLocalRepositoryFromBinary = false;
+static int sMaxConcurrentOperations = 0;
static bool componentMatches(const Component *component, const QString &name,
const QString &version = QString())
@@ -1405,6 +1406,30 @@ void PackageManagerCore::setCreateLocalRepositoryFromBinary(bool create)
sCreateLocalRepositoryFromBinary = create;
}
+/* static */
+/*!
+ Returns the maximum count of operations that should be run concurrently
+ at the given time.
+
+ Currently this affects only operations in the unpacking phase.
+*/
+int PackageManagerCore::maxConcurrentOperations()
+{
+ return sMaxConcurrentOperations;
+}
+
+/* static */
+/*!
+ Sets the maximum \a count of operations that should be run concurrently
+ at the given time. A value of \c 0 is synonym for automatic count.
+
+ Currently this affects only operations in the unpacking phase.
+*/
+void PackageManagerCore::setMaxConcurrentOperations(int count)
+{
+ sMaxConcurrentOperations = count;
+}
+
/*!
Returns \c true if the package manager is running and installed packages are
found. Otherwise, returns \c false.
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index bbc6251fc..7cce3f7be 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -119,6 +119,9 @@ public:
static bool createLocalRepositoryFromBinary();
static void setCreateLocalRepositoryFromBinary(bool create);
+ static int maxConcurrentOperations();
+ static void setMaxConcurrentOperations(int count);
+
static Component *componentByName(const QString &name, const QList<Component *> &components);
bool directoryWritable(const QString &path) const;
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 4fffcab35..cbd14b2a8 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -2203,6 +2203,8 @@ void PackageManagerCorePrivate::unpackComponents(const QList<Component *> &compo
// 3. Backup operations
ConcurrentOperationRunner runner(&unpackOperations, Operation::Backup);
+ runner.setMaxThreadCount(m_core->maxConcurrentOperations());
+
connect(m_core, &PackageManagerCore::installationInterrupted,
&runner, &ConcurrentOperationRunner::cancel);
diff --git a/src/sdk/sdkapp.h b/src/sdk/sdkapp.h
index 097886104..8a9423edc 100644
--- a/src/sdk/sdkapp.h
+++ b/src/sdk/sdkapp.h
@@ -344,6 +344,16 @@ public:
.isSet(CommandLineOptions::scCreateLocalRepositoryLong)
|| m_core->settings().createLocalRepository());
+ if (m_parser.isSet(CommandLineOptions::scMaxConcurrentOperationsLong)) {
+ bool isValid;
+ const int count = m_parser.value(CommandLineOptions::scMaxConcurrentOperationsLong).toInt(&isValid);
+ if (!isValid) {
+ errorMessage = QObject::tr("Invalid value for 'max-concurrent-operations'.");
+ return false;
+ }
+ QInstaller::PackageManagerCore::setMaxConcurrentOperations(count);
+ }
+
if (m_parser.isSet(CommandLineOptions::scAcceptLicensesLong))
m_core->setAutoAcceptLicenses();