QThreadPool: Add Quality of Service API

Same limitation as setting priority; it only applies to threads that
start after the call.

Change-Id: I0f77467a76ce2f4e7743d04fde344ef08cd8dbb8
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Mårten Nordheim 2024-10-04 15:55:38 +02:00
parent 35066b28c8
commit e58d714c47
4 changed files with 50 additions and 0 deletions

View File

@ -249,6 +249,7 @@ void QThreadPoolPrivate::startThread(QRunnable *runnable)
if (objectName.isEmpty())
objectName = u"Thread (pooled)"_s;
thread->setObjectName(objectName);
thread->setServiceLevel(serviceLevel);
Q_ASSERT(!allThreads.contains(thread.get())); // if this assert hits, we have an ABA problem (deleted threads don't get removed here)
allThreads.insert(thread.get());
++activeThreads;
@ -764,6 +765,38 @@ void QThreadPool::releaseThread()
d->tryToStartMoreThreads();
}
/*!
\since 6.9
Sets the Quality of Service level of thread objects created after the call
to this setter to \a serviceLevel.
Support is not available on every platform. Consult
QThread::setServiceLevel() for details.
\sa serviceLevel(), QThread::serviceLevel()
*/
void QThreadPool::setServiceLevel(QThread::QualityOfService serviceLevel)
{
Q_D(QThreadPool);
QMutexLocker locker(&d->mutex);
d->serviceLevel = serviceLevel;
}
/*!
\since 6.9
Returns the current Quality of Service level of the thread.
\sa setServiceLevel(), QThread::serviceLevel()
*/
QThread::QualityOfService QThreadPool::serviceLevel() const
{
Q_D(const QThreadPool);
QMutexLocker locker(&d->mutex);
return d->serviceLevel;
}
/*!
Releases a thread previously reserved with reserveThread() and uses it
to run \a runnable.

View File

@ -72,6 +72,9 @@ public:
void reserveThread();
void releaseThread();
void setServiceLevel(QThread::QualityOfService serviceLevel);
QThread::QualityOfService serviceLevel() const;
QT_CORE_INLINE_SINCE(6, 8)
bool waitForDone(int msecs);
bool waitForDone(QDeadlineTimer deadline = QDeadlineTimer::Forever);

View File

@ -149,6 +149,7 @@ public:
int activeThreads = 0;
uint stackSize = 0;
QThread::Priority threadPriority = QThread::InheritPriority;
QThread::QualityOfService serviceLevel = QThread::QualityOfService::Auto;
};
QT_END_NAMESPACE

View File

@ -76,6 +76,7 @@ private slots:
void tryStartCount();
void priorityStart_data();
void priorityStart();
void qualityOfService();
void waitForDone();
void clear();
void clearWithAutoDelete();
@ -1046,6 +1047,18 @@ void tst_QThreadPool::priorityStart()
QCOMPARE(firstStarted.loadRelaxed(), expected);
}
void tst_QThreadPool::qualityOfService()
{
QThreadPool p;
p.setServiceLevel(QThread::QualityOfService::Eco);
QThread::QualityOfService level = QThread::QualityOfService::Auto;
p.tryStart([&level](){
level = QThread::currentThread()->serviceLevel();
});
QVERIFY(p.waitForDone(QDeadlineTimer(10s)));
QCOMPARE(level, QThread::QualityOfService::Eco);
}
void tst_QThreadPool::waitForDone()
{
QElapsedTimer total, pass;