diff options
Diffstat (limited to 'src/corelib/thread/qyieldcpu.qdoc')
-rw-r--r-- | src/corelib/thread/qyieldcpu.qdoc | 59 |
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. +*/ |