From f1f29c35cba226407cc5fa20bf48b87620850b05 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 13 Sep 2019 15:18:39 +0200 Subject: [PATCH] QSemaphore: port non-futex case from (QWaitCondition, QMutex) to std::{condition_variable, mutex} The std variant is faster and more compact. Use the QtPrivate wrappers to avoid the Integrity mess. Change-Id: I4a1b1626d29472af059fee55ca26c31d9522b179 Reviewed-by: Thiago Macieira Reviewed-by: Qt CI Bot --- src/corelib/thread/qsemaphore.cpp | 53 +++++++++++++++++-------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp index 044e15d2f88..652ac16b5a9 100644 --- a/src/corelib/thread/qsemaphore.cpp +++ b/src/corelib/thread/qsemaphore.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2017 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** @@ -39,12 +39,14 @@ ****************************************************************************/ #include "qsemaphore.h" -#include "qmutex.h" #include "qfutex_p.h" -#include "qwaitcondition.h" #include "qdeadlinetimer.h" #include "qdatetime.h" #include "qdebug.h" +#include "qlocking_p.h" +#include "qwaitcondition_p.h" + +#include QT_BEGIN_NAMESPACE @@ -275,10 +277,10 @@ template bool futexSemaphoreTryAcquire(QBasicAtomicIntegermutex); - while (n > d->avail) - d->cond.wait(locker.mutex()); + const auto sufficientResourcesAvailable = [this, n] { return d->avail >= n; }; + + auto locker = qt_unique_lock(d->mutex); + d->cond.wait(locker, sufficientResourcesAvailable); d->avail -= n; } @@ -405,9 +408,9 @@ void QSemaphore::release(int n) return; } - QMutexLocker locker(&d->mutex); + const auto locker = qt_scoped_lock(d->mutex); d->avail += n; - d->cond.wakeAll(); + d->cond.notify_all(); } /*! @@ -421,7 +424,7 @@ int QSemaphore::available() const if (futexAvailable()) return futexAvailCounter(u.loadRelaxed()); - QMutexLocker locker(&d->mutex); + const auto locker = qt_scoped_lock(d->mutex); return d->avail; } @@ -443,7 +446,7 @@ bool QSemaphore::tryAcquire(int n) if (futexAvailable()) return futexSemaphoreTryAcquire(u, n, 0); - QMutexLocker locker(&d->mutex); + const auto locker = qt_scoped_lock(d->mutex); if (n > d->avail) return false; d->avail -= n; @@ -468,22 +471,24 @@ bool QSemaphore::tryAcquire(int n) */ bool QSemaphore::tryAcquire(int n, int timeout) { - Q_ASSERT_X(n >= 0, "QSemaphore::tryAcquire", "parameter 'n' must be non-negative"); + if (timeout < 0) { + acquire(n); + return true; + } - // We're documented to accept any negative value as "forever" - // but QDeadlineTimer only accepts -1. - timeout = qMax(timeout, -1); + if (timeout == 0) + return tryAcquire(n); + + Q_ASSERT_X(n >= 0, "QSemaphore::tryAcquire", "parameter 'n' must be non-negative"); if (futexAvailable()) return futexSemaphoreTryAcquire(u, n, timeout); - QDeadlineTimer timer(timeout); - QMutexLocker locker(&d->mutex); - while (n > d->avail && !timer.hasExpired()) { - if (!d->cond.wait(locker.mutex(), timer)) - return false; - } - if (n > d->avail) + using namespace std::chrono; + const auto sufficientResourcesAvailable = [this, n] { return d->avail >= n; }; + + auto locker = qt_unique_lock(d->mutex); + if (!d->cond.wait_for(locker, milliseconds{timeout}, sufficientResourcesAvailable)) return false; d->avail -= n; return true;