97#if defined(FUTEX_OP) && QT_POINTER_SIZE > 4
114 return int(
unsigned(
v));
116 return int(
v & 0x7fffffffU);
125 return unsigned(
quint64(
v) >> 32) >
unsigned(
v);
129static QBasicAtomicInteger<quint32> *
futexLow32(QBasicAtomicInteger<quintptr> *
ptr)
131 auto result =
reinterpret_cast<QBasicAtomicInteger<quint32> *
>(
ptr);
132#if Q_BYTE_ORDER == Q_BIG_ENDIAN && QT_POINTER_SIZE > 4
138static QBasicAtomicInteger<quint32> *
futexHigh32(QBasicAtomicInteger<quintptr> *
ptr)
141 auto result =
reinterpret_cast<QBasicAtomicInteger<quint32> *
>(
ptr);
142#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN && QT_POINTER_SIZE > 4
148template <
bool IsTimed>
bool
152 using namespace std::chrono;
153 int n = int(
unsigned(nn));
165 curValue =
quint64(curValue) >> 32;
177 curValue = u.loadAcquire();
182 if (u.testAndSetOrdered(curValue, newValue, curValue))
187 if (IsTimed &&
timer.hasExpired())
195template <
typename T>
bool
198 constexpr bool IsTimed = std::is_same_v<QDeadlineTimer, T>;
205 quintptr curValue = u.loadAcquire();
209 if (u.testAndSetOrdered(curValue, newValue, curValue))
212 if constexpr (IsTimed) {
226 if (waiterCount == 0x7fffffffU) {
227 qCritical() <<
"Waiter count overflow in QSemaphore";
232 u.fetchAndAddRelaxed(oneWaiter);
233 curValue += oneWaiter;
239 if (futexSemaphoreTryAcquire_loop<IsTimed>(u, curValue, nn,
timeout))
247 u.fetchAndSubRelaxed(oneWaiter);
287 Q_ASSERT_X(
n >= 0,
"QSemaphore",
"parameter 'n' must be non-negative");
319#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0)
320# warning "Move the Q_ASSERT to inline code, make QSemaphore have wide contract, " \
321 "and mark noexcept where futexes are in use."
323 Q_ASSERT_X(
n >= 0,
"QSemaphore::acquire",
"parameter 'n' must be non-negative");
331 const auto sufficientResourcesAvailable = [
this,
n] {
return d->avail >=
n; };
333 auto locker = qt_unique_lock(
d->mutex);
334 d->cond.wait(locker, sufficientResourcesAvailable);
353 Q_ASSERT_X(
n >= 0,
"QSemaphore::release",
"parameter 'n' must be non-negative");
362 newValue = prevValue + nn;
406 const auto locker = qt_scoped_lock(
d->mutex);
408 d->cond.notify_all();
422 const auto locker = qt_scoped_lock(
d->mutex);
439 Q_ASSERT_X(
n >= 0,
"QSemaphore::tryAcquire",
"parameter 'n' must be non-negative");
444 const auto locker = qt_scoped_lock(
d->mutex);
485 if (
timer.isForever()) {
490 if (
timer.hasExpired())
493 Q_ASSERT_X(
n >= 0,
"QSemaphore::tryAcquire",
"parameter 'n' must be non-negative");
498 using namespace std::chrono;
499 const auto sufficientResourcesAvailable = [
this,
n] {
return d->avail >=
n; };
501 auto locker = qt_unique_lock(
d->mutex);
502 if (!
d->cond.wait_until(locker,
timer.deadline<steady_clock>(), sufficientResourcesAvailable))
void storeRelaxed(T newValue) noexcept
bool testAndSetRelease(T expectedValue, T newValue) noexcept
T loadRelaxed() const noexcept
ForeverConstant
\value Forever Used when creating a QDeadlineTimer to indicate the deadline should not expire
static constexpr ForeverConstant Forever
QSemaphorePrivate(qsizetype n)
~QSemaphore()
Destroys the semaphore.
void acquire(int n=1)
Tries to acquire n resources guarded by the semaphore.
QBasicAtomicInteger< quintptr > u
bool tryAcquire(int n=1)
Tries to acquire n resources guarded by the semaphore and returns true on success.
void release(int n=1)
Releases n resources guarded by the semaphore.
QSemaphore(int n=0)
Creates a new semaphore and initializes the number of resources it guards to n (by default,...
int available() const
Returns the number of resources currently available to the semaphore.
Combined button and popup list for selecting options.
void futexWakeAll(Atomic &futex)
void futexWait(Atomic &futex, typename Atomic::Type expectedValue)
constexpr bool futexAvailable()
static constexpr quintptr IdealMutexAlignment
std::conditional_t< sizeof(Layout1)<=sizeof(Layout2), Layout1, Layout2 > Members
static ControlElement< T > * ptr(QWidget *widget)
GLsizei const GLfloat * v
[13]
GLbitfield GLuint64 timeout
[4]
#define Q_ASSERT_X(cond, x, msg)
static QBasicAtomicInteger< quint32 > * futexHigh32(QBasicAtomicInteger< quintptr > *ptr)
static QBasicAtomicInteger< quint32 > * futexLow32(QBasicAtomicInteger< quintptr > *ptr)
static constexpr bool futexHasWaiterCount
bool futexSemaphoreTryAcquire_loop(QBasicAtomicInteger< quintptr > &u, quintptr curValue, quintptr nn, QDeadlineTimer timer)
static bool futexNeedsWake(quintptr v)
static constexpr quintptr futexNeedsWakeAllBit
static int futexAvailCounter(quintptr v)
static constexpr QDeadlineTimer::ForeverConstant Expired
bool futexSemaphoreTryAcquire(QBasicAtomicInteger< quintptr > &u, int n, T timeout)
unsigned long long quint64
std::condition_variable cond
std::condition_variable cond