129 #if defined(FUTEX_OP) && QT_POINTER_SIZE > 4
130 static constexpr
bool futexHasWaiterCount =
true;
132 static constexpr
bool futexHasWaiterCount =
false;
135 static constexpr
quintptr futexNeedsWakeAllBit = futexHasWaiterCount ?
141 if (futexHasWaiterCount) {
146 return int(
unsigned(
v));
148 return int(
v & 0x7fffffffU);
156 if constexpr (futexHasWaiterCount)
157 return unsigned(
quint64(
v) >> 32) > unsigned(
v);
164 #if Q_BYTE_ORDER == Q_BIG_ENDIAN && QT_POINTER_SIZE > 4
174 #if Q_BYTE_ORDER == Q_LITTLE_ENDIAN && QT_POINTER_SIZE > 4
180 template <
bool IsTimed>
bool
185 int n = int(
unsigned(nn));
190 auto ptr = futexLow32(&
u);
191 if (
n > 1 || !futexHasWaiterCount) {
192 u.fetchAndOrRelaxed(futexNeedsWakeAllBit);
193 curValue |= futexNeedsWakeAllBit;
194 if constexpr (futexHasWaiterCount) {
196 ptr = futexHigh32(&
u);
201 if (IsTimed && remainingTime > 0) {
202 bool timedout = !
futexWait(*ptr, curValue, remainingTime);
209 curValue =
u.loadAcquire();
211 remainingTime =
timer.remainingTimeNSecs();
214 while (futexAvailCounter(curValue) >=
n) {
216 if (
u.testAndSetOrdered(curValue, newValue, curValue))
221 if (remainingTime == 0)
231 if (futexHasWaiterCount)
235 while (futexAvailCounter(curValue) >=
n) {
238 if (
u.testAndSetOrdered(curValue, newValue, curValue))
246 if constexpr (futexHasWaiterCount) {
249 if (((curValue >> 32) & 0x7fffffffU) == 0x7fffffffU) {
250 qCritical() <<
"Waiter count overflow in QSemaphore";
255 u.fetchAndAddRelaxed(oneWaiter);
256 curValue += oneWaiter;
262 if (futexSemaphoreTryAcquire_loop<IsTimed>(
u, curValue, nn,
timeout))
267 if (futexHasWaiterCount) {
269 Q_ASSERT(futexHigh32(&
u)->loadRelaxed() & 0x7fffffffU);
270 u.fetchAndSubRelaxed(oneWaiter);
293 Q_ASSERT_X(
n >= 0,
"QSemaphore",
"parameter 'n' must be non-negative");
296 if (futexHasWaiterCount)
325 Q_ASSERT_X(
n >= 0,
"QSemaphore::acquire",
"parameter 'n' must be non-negative");
328 futexSemaphoreTryAcquire<false>(
u,
n, -1);
334 d->cond.wait(locker.
mutex());
353 Q_ASSERT_X(
n >= 0,
"QSemaphore::release",
"parameter 'n' must be non-negative");
357 if (futexHasWaiterCount)
362 newValue = prevValue + nn;
363 newValue &= (futexNeedsWakeAllBit - 1);
364 }
while (!
u.testAndSetRelease(prevValue, newValue, prevValue));
365 if (futexNeedsWake(prevValue)) {
367 if (futexHasWaiterCount) {
386 futexWakeOp(*futexLow32(&
u),
n, INT_MAX, *futexHigh32(&
u), FUTEX_OP(
op, oparg, cmp, cmparg));
397 if (futexHasWaiterCount) {
421 return futexAvailCounter(
u.loadRelaxed());
440 Q_ASSERT_X(
n >= 0,
"QSemaphore::tryAcquire",
"parameter 'n' must be non-negative");
443 return futexSemaphoreTryAcquire<false>(
u,
n, 0);
470 Q_ASSERT_X(
n >= 0,
"QSemaphore::tryAcquire",
"parameter 'n' must be non-negative");
477 return futexSemaphoreTryAcquire<true>(
u,
n,
timeout);
481 while (
n >
d->avail && !
timer.hasExpired()) {
small capitals from c petite p scientific f u
The QDeadlineTimer class marks a deadline in the future.
The QMutex class provides access serialization between threads.
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes.
Mutex * mutex() const noexcept
constexpr bool futexAvailable()
void futexWakeAll(Atomic &)
bool futexWait(Atomic &, typename Atomic::Type, int=0)
set set set set set set set macro pixldst1 op
unsigned long long quint64
GLsizei const GLfloat * v
[13]
GLbitfield GLuint64 timeout
[4]
#define Q_ASSERT_X(cond, x, msg)
bool futexSemaphoreTryAcquire(QBasicAtomicInteger< quintptr > &u, int n, int timeout)
bool futexSemaphoreTryAcquire_loop(QBasicAtomicInteger< quintptr > &u, quintptr curValue, quintptr nn, int timeout)