summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2025-10-16 11:23:33 +0200
committerFabian Kosmale <fabian.kosmale@qt.io>2025-10-27 17:35:04 +0000
commite89d20181bcd38c25180ff7943cf48941710ead9 (patch)
tree8418bcaba37e9ea2e3b42ec407d6b7ea2bdf0d32
parent13f521e4983c7f3b4a77a4c521da1cfda992dad8 (diff)
QBasicAtomicInteger: Add (internal) refRelaxed
It is known that incrementing the refcount can use relaxed semantics, compare https://web.archive.org/web/20251016043603/https://devblogs.microsoft.com/oldnewthing/20251015-00/?p=111686 However, we can't modify QBasicAtomic::ref, because that is documented to use "ordered" semantics. So introduce a new (internal) refRelaxed method, which simply calls fetchAndAddRelaxed(1) instead. Compared to ref, we also do not return anything, as no expected user has a need for the return value (and it only causes more work for the compiler to get rid of it again). Our deref operation is still using acquire_release semantics, so everything is fine. Port QArrayData to use it as a first user so that the functionality is tested. Change-Id: I678870551fe85b83d9bb073ddb5947e649845264 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
-rw-r--r--src/corelib/thread/qatomic.cpp13
-rw-r--r--src/corelib/thread/qatomic.h1
-rw-r--r--src/corelib/thread/qbasicatomic.h1
-rw-r--r--src/corelib/tools/qarraydata.h2
4 files changed, 16 insertions, 1 deletions
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index d0e61a1cf6c..bcb92b384ae 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -316,6 +316,19 @@
*/
/*!
+ \fn template <typename T> void QAtomicInteger<T>::refRelaxed()
+ \internal
+ Atomically increments the value of this QAtomicInteger.
+
+ In contrast to ref(), this uses relaxed semantics, which is
+ all that is needed for reference counting (together with deref's
+ acquire-release semantics).
+ It also doesn't return anything.
+
+ \sa deref(), operator++()
+*/
+
+/*!
\fn template <typename T> T QAtomicInteger<T>::operator++()
\since 5.3
diff --git a/src/corelib/thread/qatomic.h b/src/corelib/thread/qatomic.h
index 4fa4fcd2ff5..2e629735128 100644
--- a/src/corelib/thread/qatomic.h
+++ b/src/corelib/thread/qatomic.h
@@ -46,6 +46,7 @@ public:
static constexpr bool isReferenceCountingWaitFree();
bool ref();
+ void refRelaxed();
bool deref();
static constexpr bool isTestAndSetNative();
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index 43337648053..49e686a9de8 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -46,6 +46,7 @@ public:
static constexpr bool isReferenceCountingWaitFree() noexcept { return Ops::isReferenceCountingWaitFree(); }
bool ref() noexcept { return Ops::ref(_q_value); }
+ void refRelaxed() noexcept { Ops::fetchAndAddRelaxed(_q_value, 1); }
bool deref() noexcept { return Ops::deref(_q_value); }
static constexpr bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); }
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index 5aadbeda538..aadf33ed5ae 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -58,7 +58,7 @@ struct QArrayData
/// Returns true if sharing took place
bool ref() noexcept
{
- ref_.ref();
+ ref_.refRelaxed(); // suffices for ref-counting
return true;
}