diff options
author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-04-24 16:43:14 +0300 |
---|---|---|
committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2023-04-24 16:43:14 +0300 |
commit | 29400a683f96867133b28299c0d0bd6bcf40df35 (patch) | |
tree | b616dfb91ce111d61a34a67b28069561306575da /src/corelib/thread/qsemaphore.cpp | |
parent | 42e4ae042a4c86e58bcb8b6d2d59ba4a988285b4 (diff) | |
parent | 9c60c8b122e5eb74fe74e11b929c30aa19ec0dd3 (diff) |
Merge remote-tracking branch 'origin/tqtc/lts-5.15.10' into tqtc/lts-5.15-opensourcev5.15.10-lts-lgpl
Change-Id: Ic1bb4240ca70a8a361fa0267476707446579221d
Diffstat (limited to 'src/corelib/thread/qsemaphore.cpp')
-rw-r--r-- | src/corelib/thread/qsemaphore.cpp | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp index 1d01fc1b28..3ecdee3747 100644 --- a/src/corelib/thread/qsemaphore.cpp +++ b/src/corelib/thread/qsemaphore.cpp @@ -354,7 +354,12 @@ void QSemaphore::release(int n) quintptr nn = unsigned(n); if (futexHasWaiterCount) nn |= quint64(nn) << 32; // token count replicated in high word - quintptr prevValue = u.fetchAndAddRelease(nn); + quintptr prevValue = u.loadRelaxed(); + quintptr newValue; + do { // loop just to ensure the operations are done atomically + newValue = prevValue + nn; + newValue &= (futexNeedsWakeAllBit - 1); + } while (!u.testAndSetRelease(prevValue, newValue, prevValue)); if (futexNeedsWake(prevValue)) { #ifdef FUTEX_OP if (futexHasWaiterCount) { @@ -376,7 +381,6 @@ void QSemaphore::release(int n) quint32 oparg = 0; quint32 cmp = FUTEX_OP_CMP_NE; quint32 cmparg = 0; - u.fetchAndAndRelease(futexNeedsWakeAllBit - 1); futexWakeOp(*futexLow32(&u), n, INT_MAX, *futexHigh32(&u), FUTEX_OP(op, oparg, cmp, cmparg)); return; } @@ -388,7 +392,6 @@ void QSemaphore::release(int n) // its acquisition anyway, so it has to wait; // 2) it did not see the new counter value, in which case its // futexWait will fail. - u.fetchAndAndRelease(futexNeedsWakeAllBit - 1); if (futexHasWaiterCount) { futexWakeAll(*futexLow32(&u)); futexWakeAll(*futexHigh32(&u)); |