summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qyieldcpu.qdoc
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/thread/qyieldcpu.qdoc')
-rw-r--r--src/corelib/thread/qyieldcpu.qdoc59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/corelib/thread/qyieldcpu.qdoc b/src/corelib/thread/qyieldcpu.qdoc
new file mode 100644
index 0000000000..c55b2c8a73
--- /dev/null
+++ b/src/corelib/thread/qyieldcpu.qdoc
@@ -0,0 +1,59 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// Copyright (C) 2023 Intel Corporation.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \fn qYieldCpu()
+ \inmodule QtCore
+ \ingroup thread
+ \relates QAtomicInteger
+ //! \relatesalso QAtomicPointer
+ \since 6.7
+
+ Pauses the execution of the current thread for an unspecified time, using
+ hardware instructions, without de-scheduling this thread. This function is
+ meant to be used in high-throughput loops where the code expects another
+ thread to modify an atomic variable. This is completely different from
+ QThread::yieldCurrentThread(), which is an OS-level operation that may take
+ the whole thread off the CPU and allow other threads (possibly belonging to
+ other processes) to run.
+
+ So, instead of
+ \code
+ while (!condition)
+ ;
+ \endcode
+
+ one should write
+ \code
+ while (!condition)
+ qYieldCpu();
+ \endcode
+
+ This is useful both with and without hardware multithreading on the same
+ core. In the case of hardware threads, it serves to prevent further
+ speculative execution filling up the pipeline, which could starve the
+ sibling thread of resources. Across cores and higher levels of separation,
+ it allows the cache coherency protocol to allocate the cache line being
+ modified and inspected to the logical processor whose result this code is
+ expecting.
+
+ It is also recommended to loop around code that does not modify the global
+ variable, to avoid contention in exclusively obtaining the memory location.
+ Therefore, an atomic modification loop such as a spinlock acquisition
+ should be:
+
+ \code
+ while (true) {
+ while (!readOnlyCondition(atomic))
+ qYieldCpu();
+ if (modify(atomic))
+ break;
+ }
+ \endcode
+
+ On x86 processors and on RISC-V processors with the \c{Zihintpause}
+ extension, this will emit the \c PAUSE instruction, which is ignored on
+ processors that don't support it; on ARMv7 or later ARM processors, it will
+ emit the \c{YIELD} instruction.
+*/