diff options
| author | Fabian Kosmale <fabian.kosmale@qt.io> | 2025-10-16 11:23:33 +0200 |
|---|---|---|
| committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2025-10-27 17:35:04 +0000 |
| commit | e89d20181bcd38c25180ff7943cf48941710ead9 (patch) | |
| tree | 8418bcaba37e9ea2e3b42ec407d6b7ea2bdf0d32 | |
| parent | 13f521e4983c7f3b4a77a4c521da1cfda992dad8 (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.cpp | 13 | ||||
| -rw-r--r-- | src/corelib/thread/qatomic.h | 1 | ||||
| -rw-r--r-- | src/corelib/thread/qbasicatomic.h | 1 | ||||
| -rw-r--r-- | src/corelib/tools/qarraydata.h | 2 |
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; } |
