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 <thiago.macieira@intel.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
6608e63298
commit
f1f29c35cb
@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2017 The Qt Company Ltd.
|
** Copyright (C) 2022 The Qt Company Ltd.
|
||||||
** Copyright (C) 2018 Intel Corporation.
|
** Copyright (C) 2018 Intel Corporation.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -39,12 +39,14 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qsemaphore.h"
|
#include "qsemaphore.h"
|
||||||
#include "qmutex.h"
|
|
||||||
#include "qfutex_p.h"
|
#include "qfutex_p.h"
|
||||||
#include "qwaitcondition.h"
|
|
||||||
#include "qdeadlinetimer.h"
|
#include "qdeadlinetimer.h"
|
||||||
#include "qdatetime.h"
|
#include "qdatetime.h"
|
||||||
#include "qdebug.h"
|
#include "qdebug.h"
|
||||||
|
#include "qlocking_p.h"
|
||||||
|
#include "qwaitcondition_p.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -275,10 +277,10 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
|
|||||||
|
|
||||||
class QSemaphorePrivate {
|
class QSemaphorePrivate {
|
||||||
public:
|
public:
|
||||||
inline QSemaphorePrivate(int n) : avail(n) { }
|
explicit QSemaphorePrivate(int n) : avail(n) { }
|
||||||
|
|
||||||
QMutex mutex;
|
QtPrivate::mutex mutex;
|
||||||
QWaitCondition cond;
|
QtPrivate::condition_variable cond;
|
||||||
|
|
||||||
int avail;
|
int avail;
|
||||||
};
|
};
|
||||||
@ -330,9 +332,10 @@ void QSemaphore::acquire(int n)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&d->mutex);
|
const auto sufficientResourcesAvailable = [this, n] { return d->avail >= n; };
|
||||||
while (n > d->avail)
|
|
||||||
d->cond.wait(locker.mutex());
|
auto locker = qt_unique_lock(d->mutex);
|
||||||
|
d->cond.wait(locker, sufficientResourcesAvailable);
|
||||||
d->avail -= n;
|
d->avail -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,9 +408,9 @@ void QSemaphore::release(int n)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&d->mutex);
|
const auto locker = qt_scoped_lock(d->mutex);
|
||||||
d->avail += n;
|
d->avail += n;
|
||||||
d->cond.wakeAll();
|
d->cond.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -421,7 +424,7 @@ int QSemaphore::available() const
|
|||||||
if (futexAvailable())
|
if (futexAvailable())
|
||||||
return futexAvailCounter(u.loadRelaxed());
|
return futexAvailCounter(u.loadRelaxed());
|
||||||
|
|
||||||
QMutexLocker locker(&d->mutex);
|
const auto locker = qt_scoped_lock(d->mutex);
|
||||||
return d->avail;
|
return d->avail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,7 +446,7 @@ bool QSemaphore::tryAcquire(int n)
|
|||||||
if (futexAvailable())
|
if (futexAvailable())
|
||||||
return futexSemaphoreTryAcquire<false>(u, n, 0);
|
return futexSemaphoreTryAcquire<false>(u, n, 0);
|
||||||
|
|
||||||
QMutexLocker locker(&d->mutex);
|
const auto locker = qt_scoped_lock(d->mutex);
|
||||||
if (n > d->avail)
|
if (n > d->avail)
|
||||||
return false;
|
return false;
|
||||||
d->avail -= n;
|
d->avail -= n;
|
||||||
@ -468,22 +471,24 @@ bool QSemaphore::tryAcquire(int n)
|
|||||||
*/
|
*/
|
||||||
bool QSemaphore::tryAcquire(int n, int timeout)
|
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"
|
if (timeout == 0)
|
||||||
// but QDeadlineTimer only accepts -1.
|
return tryAcquire(n);
|
||||||
timeout = qMax(timeout, -1);
|
|
||||||
|
Q_ASSERT_X(n >= 0, "QSemaphore::tryAcquire", "parameter 'n' must be non-negative");
|
||||||
|
|
||||||
if (futexAvailable())
|
if (futexAvailable())
|
||||||
return futexSemaphoreTryAcquire<true>(u, n, timeout);
|
return futexSemaphoreTryAcquire<true>(u, n, timeout);
|
||||||
|
|
||||||
QDeadlineTimer timer(timeout);
|
using namespace std::chrono;
|
||||||
QMutexLocker locker(&d->mutex);
|
const auto sufficientResourcesAvailable = [this, n] { return d->avail >= n; };
|
||||||
while (n > d->avail && !timer.hasExpired()) {
|
|
||||||
if (!d->cond.wait(locker.mutex(), timer))
|
auto locker = qt_unique_lock(d->mutex);
|
||||||
return false;
|
if (!d->cond.wait_for(locker, milliseconds{timeout}, sufficientResourcesAvailable))
|
||||||
}
|
|
||||||
if (n > d->avail)
|
|
||||||
return false;
|
return false;
|
||||||
d->avail -= n;
|
d->avail -= n;
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user