summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-03-31 01:00:13 +0200
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-03-31 01:00:13 +0200
commitffb2c2ac6c3ba40acbe13a39899a72049585b427 (patch)
treedbee14e6d1641e02ea1fd5fc67ce001ab12776ef /src/corelib
parent6d0044f1dcffebc29dccd9d37d90f8abdb941a88 (diff)
parentdbdd5f0ffbce52c8b789ed09f1aa3f1da6c02e23 (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp6
-rw-r--r--src/corelib/thread/qsemaphore.cpp33
2 files changed, 23 insertions, 16 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
index a17e541df3..d163129d54 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp
@@ -395,10 +395,10 @@ QByteArray ba = QByteArray::number(12.3456, 'E', 3);
//! [43]
static const char mydata[] = {
- 0x00, 0x00, 0x03, 0x84, 0x78, 0x9c, 0x3b, 0x76,
- 0xec, 0x18, 0xc3, 0x31, 0x0a, 0xf1, 0xcc, 0x99,
+ '\x00', '\x00', '\x03', '\x84', '\x78', '\x9c', '\x3b', '\x76',
+ '\xec', '\x18', '\xc3', '\x31', '\x0a', '\xf1', '\xcc', '\x99',
...
- 0x6d, 0x5b
+ '\x6d', '\x5b'
};
QByteArray data = QByteArray::fromRawData(mydata, sizeof(mydata));
diff --git a/src/corelib/thread/qsemaphore.cpp b/src/corelib/thread/qsemaphore.cpp
index 6c4a211222..9a5505bd1e 100644
--- a/src/corelib/thread/qsemaphore.cpp
+++ b/src/corelib/thread/qsemaphore.cpp
@@ -120,12 +120,12 @@ using namespace QtFutex;
If the system has the ability to wake up a precise number of threads, has
Linux's FUTEX_WAKE_OP functionality, and is 64-bit, instead of using a
- single bit indicating a contended semaphore, we'll store the total number
- of waiters in the high word. Additionally, all multi-token waiters will be
- waiting on that high word. So when releasing n tokens on those systems, we
- tell the kernel to wake up n single-token threads and all of the
- multi-token ones. Which threads get woken up is unspecified, but it's
- likely single-token threads will get woken up first.
+ single bit indicating a contended semaphore, we'll store the number of
+ tokens *plus* total number of waiters in the high word. Additionally, all
+ multi-token waiters will be waiting on that high word. So when releasing n
+ tokens on those systems, we tell the kernel to wake up n single-token
+ threads and all of the multi-token ones. Which threads get woken up is
+ unspecified, but it's likely single-token threads will get woken up first.
*/
#if defined(FUTEX_OP) && QT_POINTER_SIZE > 4
@@ -231,10 +231,14 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
{
// Try to acquire without waiting (we still loop because the testAndSet
// call can fail).
+ quintptr nn = unsigned(n);
+ if (futexHasWaiterCount)
+ nn |= quint64(nn) << 32; // token count replicated in high word
+
quintptr curValue = u.loadAcquire();
while (futexAvailCounter(curValue) >= n) {
// try to acquire
- quintptr newValue = curValue - n;
+ quintptr newValue = curValue - nn;
if (u.testAndSetOrdered(curValue, newValue, curValue))
return true; // succeeded!
}
@@ -242,7 +246,6 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
return false;
// we need to wait
- quintptr valueToSubtract = unsigned(n);
quintptr oneWaiter = quintptr(Q_UINT64_C(1) << 32); // zero on 32-bit
if (futexHasWaiterCount) {
// increase the waiter count
@@ -250,14 +253,15 @@ template <bool IsTimed> bool futexSemaphoreTryAcquire(QBasicAtomicInteger<quintp
// We don't use the fetched value from above so futexWait() fails if
// it changed after the testAndSetOrdered above.
+ if ((quint64(curValue) >> 32) == 0x7fffffff)
+ return false; // overflow!
curValue += oneWaiter;
- // Also adjust valueToSubtract to subtract oneWaiter when we succeed in
- // acquiring.
- valueToSubtract += oneWaiter;
+ // Also adjust nn to subtract oneWaiter when we succeed in acquiring.
+ nn += oneWaiter;
}
- if (futexSemaphoreTryAcquire_loop<IsTimed>(u, curValue, valueToSubtract, timeout))
+ if (futexSemaphoreTryAcquire_loop<IsTimed>(u, curValue, nn, timeout))
return true;
if (futexHasWaiterCount) {
@@ -345,7 +349,10 @@ void QSemaphore::release(int n)
Q_ASSERT_X(n >= 0, "QSemaphore::release", "parameter 'n' must be non-negative");
if (futexAvailable()) {
- quintptr prevValue = u.fetchAndAddRelease(n);
+ quintptr nn = unsigned(n);
+ if (futexHasWaiterCount)
+ nn |= quint64(nn) << 32; // token count replicated in high word
+ quintptr prevValue = u.fetchAndAddRelease(nn);
if (futexNeedsWake(prevValue)) {
#ifdef FUTEX_OP
if (!futexHasWaiterCount) {