One Hat Cyber Team
Your IP :
216.73.216.115
Server IP :
194.44.31.54
Server :
Linux zen.imath.kiev.ua 4.18.0-553.77.1.el8_10.x86_64 #1 SMP Fri Oct 3 14:30:23 UTC 2025 x86_64
Server Software :
Apache/2.4.37 (Rocky Linux) OpenSSL/1.1.1k
PHP Version :
5.6.40
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
doc
/
qemu-kvm
/
devel
/
View File Name :
atomics.html
<!DOCTYPE html> <!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]--> <!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]--> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Atomic operations in QEMU — QEMU qemu-kvm-6.2.0-53.module+el8.10.0+2055+8eb7870b.4 documentation</title> <link rel="shortcut icon" href="../_static/qemu_32x32.png"/> <link rel="stylesheet" href="../_static/css/theme.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <link rel="index" title="Index" href="../genindex.html" /> <link rel="search" title="Search" href="../search.html" /> <link rel="next" title="QEMU and the stable process" href="stable-process.html" /> <link rel="prev" title="Migration" href="migration.html" /> <script src="../_static/js/modernizr.min.js"></script> </head> <body class="wy-body-for-nav"> <div class="wy-grid-for-nav"> <nav data-toggle="wy-nav-shift" class="wy-nav-side"> <div class="wy-side-scroll"> <div class="wy-side-nav-search"> <a href="../index.html" class="icon icon-home"> QEMU <img src="../_static/qemu_128x128.png" class="logo" alt="Logo"/> </a> <div class="version"> 6.2.0 </div> <div role="search"> <form id="rtd-search-form" class="wy-form" action="../search.html" method="get"> <input type="text" name="q" placeholder="Search docs" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> </div> </div> <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation"> <p class="caption"><span class="caption-text">Contents:</span></p> <ul class="current"> <li class="toctree-l1"><a class="reference internal" href="../about/index.html">About QEMU</a></li> <li class="toctree-l1"><a class="reference internal" href="../system/index.html">System Emulation</a></li> <li class="toctree-l1"><a class="reference internal" href="../user/index.html">User Mode Emulation</a></li> <li class="toctree-l1"><a class="reference internal" href="../tools/index.html">Tools</a></li> <li class="toctree-l1"><a class="reference internal" href="../interop/index.html">System Emulation Management and Interoperability</a></li> <li class="toctree-l1"><a class="reference internal" href="../specs/index.html">System Emulation Guest Hardware Specifications</a></li> <li class="toctree-l1 current"><a class="reference internal" href="index.html">Developer Information</a><ul class="current"> <li class="toctree-l2"><a class="reference internal" href="code-of-conduct.html">Code of Conduct</a></li> <li class="toctree-l2"><a class="reference internal" href="conflict-resolution.html">Conflict Resolution Policy</a></li> <li class="toctree-l2"><a class="reference internal" href="build-system.html">The QEMU build system architecture</a></li> <li class="toctree-l2"><a class="reference internal" href="style.html">QEMU Coding Style</a></li> <li class="toctree-l2"><a class="reference internal" href="kconfig.html">QEMU and Kconfig</a></li> <li class="toctree-l2"><a class="reference internal" href="testing.html">Testing in QEMU</a></li> <li class="toctree-l2"><a class="reference internal" href="fuzzing.html">Fuzzing</a></li> <li class="toctree-l2"><a class="reference internal" href="control-flow-integrity.html">Control-Flow Integrity (CFI)</a></li> <li class="toctree-l2"><a class="reference internal" href="loads-stores.html">Load and Store APIs</a></li> <li class="toctree-l2"><a class="reference internal" href="memory.html">The memory API</a></li> <li class="toctree-l2"><a class="reference internal" href="migration.html">Migration</a></li> <li class="toctree-l2 current"><a class="current reference internal" href="#">Atomic operations in QEMU</a><ul> <li class="toctree-l3"><a class="reference internal" href="#compiler-memory-barrier">Compiler memory barrier</a></li> <li class="toctree-l3"><a class="reference internal" href="#sequentially-consistent-atomic-access">Sequentially consistent atomic access</a></li> <li class="toctree-l3"><a class="reference internal" href="#weak-atomic-access-and-manual-memory-barriers">Weak atomic access and manual memory barriers</a><ul> <li class="toctree-l4"><a class="reference internal" href="#acquire-release-pairing-and-the-synchronizes-with-relation">Acquire/release pairing and the <em>synchronizes-with</em> relation</a></li> </ul> </li> <li class="toctree-l3"><a class="reference internal" href="#comparison-with-linux-kernel-primitives">Comparison with Linux kernel primitives</a></li> <li class="toctree-l3"><a class="reference internal" href="#sources">Sources</a></li> </ul> </li> <li class="toctree-l2"><a class="reference internal" href="stable-process.html">QEMU and the stable process</a></li> <li class="toctree-l2"><a class="reference internal" href="ci.html">CI</a></li> <li class="toctree-l2"><a class="reference internal" href="qtest.html">QTest Device Emulation Testing Framework</a></li> <li class="toctree-l2"><a class="reference internal" href="decodetree.html">Decodetree Specification</a></li> <li class="toctree-l2"><a class="reference internal" href="secure-coding-practices.html">Secure Coding Practices</a></li> <li class="toctree-l2"><a class="reference internal" href="tcg.html">Translator Internals</a></li> <li class="toctree-l2"><a class="reference internal" href="tcg-icount.html">TCG Instruction Counting</a></li> <li class="toctree-l2"><a class="reference internal" href="tracing.html">Tracing</a></li> <li class="toctree-l2"><a class="reference internal" href="multi-thread-tcg.html">Multi-threaded TCG</a></li> <li class="toctree-l2"><a class="reference internal" href="tcg-plugins.html">QEMU TCG Plugins</a></li> <li class="toctree-l2"><a class="reference internal" href="bitops.html">Bitwise operations</a></li> <li class="toctree-l2"><a class="reference internal" href="ui.html">QEMU UI subsystem</a></li> <li class="toctree-l2"><a class="reference internal" href="reset.html">Reset in QEMU: the Resettable interface</a></li> <li class="toctree-l2"><a class="reference internal" href="s390-dasd-ipl.html">Booting from real channel-attached devices on s390x</a></li> <li class="toctree-l2"><a class="reference internal" href="clocks.html">Modelling a clock tree in QEMU</a></li> <li class="toctree-l2"><a class="reference internal" href="qom.html">The QEMU Object Model (QOM)</a></li> <li class="toctree-l2"><a class="reference internal" href="modules.html">QEMU modules</a></li> <li class="toctree-l2"><a class="reference internal" href="block-coroutine-wrapper.html">block-coroutine-wrapper</a></li> <li class="toctree-l2"><a class="reference internal" href="multi-process.html">Multi-process QEMU</a></li> <li class="toctree-l2"><a class="reference internal" href="ebpf_rss.html">eBPF RSS virtio-net support</a></li> <li class="toctree-l2"><a class="reference internal" href="vfio-migration.html">VFIO device Migration</a></li> <li class="toctree-l2"><a class="reference internal" href="qapi-code-gen.html">How to use the QAPI code generator</a></li> <li class="toctree-l2"><a class="reference internal" href="writing-monitor-commands.html">How to write monitor commands</a></li> <li class="toctree-l2"><a class="reference internal" href="trivial-patches.html">Trivial Patches</a></li> <li class="toctree-l2"><a class="reference internal" href="submitting-a-patch.html">Submitting a Patch</a></li> <li class="toctree-l2"><a class="reference internal" href="submitting-a-pull-request.html">Submitting a Pull Request</a></li> </ul> </li> </ul> </div> </div> </nav> <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"> <nav class="wy-nav-top" aria-label="top navigation"> <i data-toggle="wy-nav-top" class="fa fa-bars"></i> <a href="../index.html">QEMU</a> </nav> <div class="wy-nav-content"> <div class="rst-content"> <div role="navigation" aria-label="breadcrumbs navigation"> <ul class="wy-breadcrumbs"> <li><a href="../index.html">Docs</a> »</li> <li><a href="index.html">Developer Information</a> »</li> <li>Atomic operations in QEMU</li> <li class="wy-breadcrumbs-aside"> <a href="https://gitlab.com/qemu-project/qemu/blob/master/docs/devel/atomics.rst" class="fa fa-gitlab"> Edit on GitLab</a> </li> </ul> <hr/> </div> <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article"> <div itemprop="articleBody"> <div class="section" id="atomic-operations-in-qemu"> <h1>Atomic operations in QEMU<a class="headerlink" href="#atomic-operations-in-qemu" title="Permalink to this headline">¶</a></h1> <p>CPUs perform independent memory operations effectively in random order. but this can be a problem for CPU-CPU interaction (including interactions between QEMU and the guest). Multi-threaded programs use various tools to instruct the compiler and the CPU to restrict the order to something that is consistent with the expectations of the programmer.</p> <p>The most basic tool is locking. Mutexes, condition variables and semaphores are used in QEMU, and should be the default approach to synchronization. Anything else is considerably harder, but it’s also justified more often than one would like; the most performance-critical parts of QEMU in particular require a very low level approach to concurrency, involving memory barriers and atomic operations. The semantics of concurrent memory accesses are governed by the C11 memory model.</p> <p>QEMU provides a header, <code class="docutils literal notranslate"><span class="pre">qemu/atomic.h</span></code>, which wraps C11 atomics to provide better portability and a less verbose syntax. <code class="docutils literal notranslate"><span class="pre">qemu/atomic.h</span></code> provides macros that fall in three camps:</p> <ul class="simple"> <li>compiler barriers: <code class="docutils literal notranslate"><span class="pre">barrier()</span></code>;</li> <li>weak atomic access and manual memory barriers: <code class="docutils literal notranslate"><span class="pre">qatomic_read()</span></code>, <code class="docutils literal notranslate"><span class="pre">qatomic_set()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_rmb()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_wmb()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_mb()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_mb_acquire()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_mb_release()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_read_barrier_depends()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_mb__before_rmw()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_mb__after_rmw()</span></code>;</li> <li>sequentially consistent atomic access: everything else.</li> </ul> <p>In general, use of <code class="docutils literal notranslate"><span class="pre">qemu/atomic.h</span></code> should be wrapped with more easily used data structures (e.g. the lock-free singly-linked list operations <code class="docutils literal notranslate"><span class="pre">QSLIST_INSERT_HEAD_ATOMIC</span></code> and <code class="docutils literal notranslate"><span class="pre">QSLIST_MOVE_ATOMIC</span></code>) or synchronization primitives (such as RCU, <code class="docutils literal notranslate"><span class="pre">QemuEvent</span></code> or <code class="docutils literal notranslate"><span class="pre">QemuLockCnt</span></code>). Bare use of atomic operations and memory barriers should be limited to inter-thread checking of flags and documented thoroughly.</p> <div class="section" id="compiler-memory-barrier"> <h2>Compiler memory barrier<a class="headerlink" href="#compiler-memory-barrier" title="Permalink to this headline">¶</a></h2> <p><code class="docutils literal notranslate"><span class="pre">barrier()</span></code> prevents the compiler from moving the memory accesses on either side of it to the other side. The compiler barrier has no direct effect on the CPU, which may then reorder things however it wishes.</p> <p><code class="docutils literal notranslate"><span class="pre">barrier()</span></code> is mostly used within <code class="docutils literal notranslate"><span class="pre">qemu/atomic.h</span></code> itself. On some architectures, CPU guarantees are strong enough that blocking compiler optimizations already ensures the correct order of execution. In this case, <code class="docutils literal notranslate"><span class="pre">qemu/atomic.h</span></code> will reduce stronger memory barriers to simple compiler barriers.</p> <p>Still, <code class="docutils literal notranslate"><span class="pre">barrier()</span></code> can be useful when writing code that can be interrupted by signal handlers.</p> </div> <div class="section" id="sequentially-consistent-atomic-access"> <h2>Sequentially consistent atomic access<a class="headerlink" href="#sequentially-consistent-atomic-access" title="Permalink to this headline">¶</a></h2> <p>Most of the operations in the <code class="docutils literal notranslate"><span class="pre">qemu/atomic.h</span></code> header ensure <em>sequential consistency</em>, where “the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program”.</p> <p><code class="docutils literal notranslate"><span class="pre">qemu/atomic.h</span></code> provides the following set of atomic read-modify-write operations:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">void</span> <span class="n">qatomic_inc</span><span class="p">(</span><span class="n">ptr</span><span class="p">)</span> <span class="n">void</span> <span class="n">qatomic_dec</span><span class="p">(</span><span class="n">ptr</span><span class="p">)</span> <span class="n">void</span> <span class="n">qatomic_add</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">void</span> <span class="n">qatomic_sub</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">void</span> <span class="n">qatomic_and</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">void</span> <span class="n">qatomic_or</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_fetch_inc</span><span class="p">(</span><span class="n">ptr</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_fetch_dec</span><span class="p">(</span><span class="n">ptr</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_fetch_add</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_fetch_sub</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_fetch_and</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_fetch_or</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_fetch_xor</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_fetch_inc_nonzero</span><span class="p">(</span><span class="n">ptr</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_xchg</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_cmpxchg</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">old</span><span class="p">,</span> <span class="n">new</span><span class="p">)</span> </pre></div> </div> <p>all of which return the old value of <code class="docutils literal notranslate"><span class="pre">*ptr</span></code>. These operations are polymorphic; they operate on any type that is as wide as a pointer or smaller.</p> <p>Similar operations return the new value of <code class="docutils literal notranslate"><span class="pre">*ptr</span></code>:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_inc_fetch</span><span class="p">(</span><span class="n">ptr</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_dec_fetch</span><span class="p">(</span><span class="n">ptr</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_add_fetch</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_sub_fetch</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_and_fetch</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_or_fetch</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> <span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_xor_fetch</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> </pre></div> </div> <p><code class="docutils literal notranslate"><span class="pre">qemu/atomic.h</span></code> also provides loads and stores that cannot be reordered with each other:</p> <div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">typeof</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">)</span> <span class="n">qatomic_mb_read</span><span class="p">(</span><span class="n">ptr</span><span class="p">)</span> <span class="n">void</span> <span class="n">qatomic_mb_set</span><span class="p">(</span><span class="n">ptr</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span> </pre></div> </div> <p>However these do not provide sequential consistency and, in particular, they do not participate in the total ordering enforced by sequentially-consistent operations. For this reason they are deprecated. They should instead be replaced with any of the following (ordered from easiest to hardest):</p> <ul class="simple"> <li>accesses inside a mutex or spinlock</li> <li>lightweight synchronization primitives such as <code class="docutils literal notranslate"><span class="pre">QemuEvent</span></code></li> <li>RCU operations (<code class="docutils literal notranslate"><span class="pre">qatomic_rcu_read</span></code>, <code class="docutils literal notranslate"><span class="pre">qatomic_rcu_set</span></code>) when publishing or accessing a new version of a data structure</li> <li>other atomic accesses: <code class="docutils literal notranslate"><span class="pre">qatomic_read</span></code> and <code class="docutils literal notranslate"><span class="pre">qatomic_load_acquire</span></code> for loads, <code class="docutils literal notranslate"><span class="pre">qatomic_set</span></code> and <code class="docutils literal notranslate"><span class="pre">qatomic_store_release</span></code> for stores, <code class="docutils literal notranslate"><span class="pre">smp_mb</span></code> to forbid reordering subsequent loads before a store.</li> </ul> </div> <div class="section" id="weak-atomic-access-and-manual-memory-barriers"> <h2>Weak atomic access and manual memory barriers<a class="headerlink" href="#weak-atomic-access-and-manual-memory-barriers" title="Permalink to this headline">¶</a></h2> <p>Compared to sequentially consistent atomic access, programming with weaker consistency models can be considerably more complicated. The only guarantees that you can rely upon in this case are:</p> <ul class="simple"> <li>atomic accesses will not cause data races (and hence undefined behavior); ordinary accesses instead cause data races if they are concurrent with other accesses of which at least one is a write. In order to ensure this, the compiler will not optimize accesses out of existence, create unsolicited accesses, or perform other similar optimzations.</li> <li>acquire operations will appear to happen, with respect to the other components of the system, before all the LOAD or STORE operations specified afterwards.</li> <li>release operations will appear to happen, with respect to the other components of the system, after all the LOAD or STORE operations specified before.</li> <li>release operations will <em>synchronize with</em> acquire operations; see <a class="reference internal" href="#acqrel"><span class="std std-ref">Acquire/release pairing and the synchronizes-with relation</span></a> for a detailed explanation.</li> </ul> <p>When using this model, variables are accessed with:</p> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">qatomic_read()</span></code> and <code class="docutils literal notranslate"><span class="pre">qatomic_set()</span></code>; these prevent the compiler from optimizing accesses out of existence and creating unsolicited accesses, but do not otherwise impose any ordering on loads and stores: both the compiler and the processor are free to reorder them.</li> <li><code class="docutils literal notranslate"><span class="pre">qatomic_load_acquire()</span></code>, which guarantees the LOAD to appear to happen, with respect to the other components of the system, before all the LOAD or STORE operations specified afterwards. Operations coming before <code class="docutils literal notranslate"><span class="pre">qatomic_load_acquire()</span></code> can still be reordered after it.</li> <li><code class="docutils literal notranslate"><span class="pre">qatomic_store_release()</span></code>, which guarantees the STORE to appear to happen, with respect to the other components of the system, after all the LOAD or STORE operations specified before. Operations coming after <code class="docutils literal notranslate"><span class="pre">qatomic_store_release()</span></code> can still be reordered before it.</li> </ul> <p>Restrictions to the ordering of accesses can also be specified using the memory barrier macros: <code class="docutils literal notranslate"><span class="pre">smp_rmb()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_wmb()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_mb()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_mb_acquire()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_mb_release()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_read_barrier_depends()</span></code>.</p> <p>Memory barriers control the order of references to shared memory. They come in six kinds:</p> <ul> <li><p class="first"><code class="docutils literal notranslate"><span class="pre">smp_rmb()</span></code> guarantees that all the LOAD operations specified before the barrier will appear to happen before all the LOAD operations specified after the barrier with respect to the other components of the system.</p> <p>In other words, <code class="docutils literal notranslate"><span class="pre">smp_rmb()</span></code> puts a partial ordering on loads, but is not required to have any effect on stores.</p> </li> <li><p class="first"><code class="docutils literal notranslate"><span class="pre">smp_wmb()</span></code> guarantees that all the STORE operations specified before the barrier will appear to happen before all the STORE operations specified after the barrier with respect to the other components of the system.</p> <p>In other words, <code class="docutils literal notranslate"><span class="pre">smp_wmb()</span></code> puts a partial ordering on stores, but is not required to have any effect on loads.</p> </li> <li><p class="first"><code class="docutils literal notranslate"><span class="pre">smp_mb_acquire()</span></code> guarantees that all the LOAD operations specified before the barrier will appear to happen before all the LOAD or STORE operations specified after the barrier with respect to the other components of the system.</p> </li> <li><p class="first"><code class="docutils literal notranslate"><span class="pre">smp_mb_release()</span></code> guarantees that all the STORE operations specified <em>after</em> the barrier will appear to happen after all the LOAD or STORE operations specified <em>before</em> the barrier with respect to the other components of the system.</p> </li> <li><p class="first"><code class="docutils literal notranslate"><span class="pre">smp_mb()</span></code> guarantees that all the LOAD and STORE operations specified before the barrier will appear to happen before all the LOAD and STORE operations specified after the barrier with respect to the other components of the system.</p> <p><code class="docutils literal notranslate"><span class="pre">smp_mb()</span></code> puts a partial ordering on both loads and stores. It is stronger than both a read and a write memory barrier; it implies both <code class="docutils literal notranslate"><span class="pre">smp_mb_acquire()</span></code> and <code class="docutils literal notranslate"><span class="pre">smp_mb_release()</span></code>, but it also prevents STOREs coming before the barrier from overtaking LOADs coming after the barrier and vice versa.</p> </li> <li><p class="first"><code class="docutils literal notranslate"><span class="pre">smp_read_barrier_depends()</span></code> is a weaker kind of read barrier. On most processors, whenever two loads are performed such that the second depends on the result of the first (e.g., the first load retrieves the address to which the second load will be directed), the processor will guarantee that the first LOAD will appear to happen before the second with respect to the other components of the system. However, this is not always true—for example, it was not true on Alpha processors. Whenever this kind of access happens to shared memory (that is not protected by a lock), a read barrier is needed, and <code class="docutils literal notranslate"><span class="pre">smp_read_barrier_depends()</span></code> can be used instead of <code class="docutils literal notranslate"><span class="pre">smp_rmb()</span></code>.</p> <p>Note that the first load really has to have a _data_ dependency and not a control dependency. If the address for the second load is dependent on the first load, but the dependency is through a conditional rather than actually loading the address itself, then it’s a _control_ dependency and a full read barrier or better is required.</p> </li> </ul> <p>Memory barriers and <code class="docutils literal notranslate"><span class="pre">qatomic_load_acquire</span></code>/<code class="docutils literal notranslate"><span class="pre">qatomic_store_release</span></code> are mostly used when a data structure has one thread that is always a writer and one thread that is always a reader:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="50%" /> <col width="50%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">thread 1</th> <th class="head">thread 2</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">qatomic_store_release</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span> <span class="n">qatomic_store_release</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">,</span> <span class="n">y</span><span class="p">);</span> </pre></div> </div> </td> <td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">y</span> <span class="o">=</span> <span class="n">qatomic_load_acquire</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">);</span> <span class="n">x</span> <span class="o">=</span> <span class="n">qatomic_load_acquire</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">);</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> <p>In this case, correctness is easy to check for using the “pairing” trick that is explained below.</p> <p>Sometimes, a thread is accessing many variables that are otherwise unrelated to each other (for example because, apart from the current thread, exactly one other thread will read or write each of these variables). In this case, it is possible to “hoist” the barriers outside a loop. For example:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="55%" /> <col width="45%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">before</th> <th class="head">after</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">n</span> <span class="o">+=</span> <span class="n">qatomic_load_acquire</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> </pre></div> </div> </td> <td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">n</span> <span class="o">+=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> <span class="n">smp_mb_acquire</span><span class="p">();</span> </pre></div> </div> </td> </tr> <tr class="row-odd"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">qatomic_store_release</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">false</span><span class="p">);</span> </pre></div> </div> </td> <td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">smp_mb_release</span><span class="p">();</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">qatomic_set</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">false</span><span class="p">);</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> <p>Splitting a loop can also be useful to reduce the number of barriers:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="55%" /> <col width="45%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">before</th> <th class="head">after</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">qatomic_store_release</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">false</span><span class="p">);</span> <span class="n">smp_mb</span><span class="p">();</span> <span class="n">n</span> <span class="o">+=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> <span class="p">}</span> </pre></div> </div> </td> <td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">smp_mb_release</span><span class="p">();</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">qatomic_set</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">false</span><span class="p">);</span> <span class="n">smb_mb</span><span class="p">();</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">n</span> <span class="o">+=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> <p>In this case, a <code class="docutils literal notranslate"><span class="pre">smp_mb_release()</span></code> is also replaced with a (possibly cheaper, and clearer as well) <code class="docutils literal notranslate"><span class="pre">smp_wmb()</span></code>:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="55%" /> <col width="45%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">before</th> <th class="head">after</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span> <span class="n">qatomic_store_release</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">false</span><span class="p">);</span> <span class="n">qatomic_store_release</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">false</span><span class="p">);</span> <span class="p">}</span> </pre></div> </div> </td> <td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">smp_mb_release</span><span class="p">();</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">qatomic_set</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">false</span><span class="p">);</span> <span class="n">smb_wmb</span><span class="p">();</span> <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">qatomic_set</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">false</span><span class="p">);</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> <div class="section" id="acquire-release-pairing-and-the-synchronizes-with-relation"> <span id="acqrel"></span><h3>Acquire/release pairing and the <em>synchronizes-with</em> relation<a class="headerlink" href="#acquire-release-pairing-and-the-synchronizes-with-relation" title="Permalink to this headline">¶</a></h3> <p>Atomic operations other than <code class="docutils literal notranslate"><span class="pre">qatomic_set()</span></code> and <code class="docutils literal notranslate"><span class="pre">qatomic_read()</span></code> have either <em>acquire</em> or <em>release</em> semantics <a class="footnote-reference" href="#rmw" id="id1">[1]</a>. This has two effects:</p> <table class="docutils footnote" frame="void" id="rmw" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> <tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>Read-modify-write operations can have both—acquire applies to the read part, and release to the write.</td></tr> </tbody> </table> <ul class="simple"> <li>within a thread, they are ordered either before subsequent operations (for acquire) or after previous operations (for release).</li> <li>if a release operation in one thread <em>synchronizes with</em> an acquire operation in another thread, the ordering constraints propagates from the first to the second thread. That is, everything before the release operation in the first thread is guaranteed to <em>happen before</em> everything after the acquire operation in the second thread.</li> </ul> <p>The concept of acquire and release semantics is not exclusive to atomic operations; almost all higher-level synchronization primitives also have acquire or release semantics. For example:</p> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">pthread_mutex_lock</span></code> has acquire semantics, <code class="docutils literal notranslate"><span class="pre">pthread_mutex_unlock</span></code> has release semantics and synchronizes with a <code class="docutils literal notranslate"><span class="pre">pthread_mutex_lock</span></code> for the same mutex.</li> <li><code class="docutils literal notranslate"><span class="pre">pthread_cond_signal</span></code> and <code class="docutils literal notranslate"><span class="pre">pthread_cond_broadcast</span></code> have release semantics; <code class="docutils literal notranslate"><span class="pre">pthread_cond_wait</span></code> has both release semantics (synchronizing with <code class="docutils literal notranslate"><span class="pre">pthread_mutex_lock</span></code>) and acquire semantics (synchronizing with <code class="docutils literal notranslate"><span class="pre">pthread_mutex_unlock</span></code> and signaling of the condition variable).</li> <li><code class="docutils literal notranslate"><span class="pre">pthread_create</span></code> has release semantics and synchronizes with the start of the new thread; <code class="docutils literal notranslate"><span class="pre">pthread_join</span></code> has acquire semantics and synchronizes with the exiting of the thread.</li> <li><code class="docutils literal notranslate"><span class="pre">qemu_event_set</span></code> has release semantics, <code class="docutils literal notranslate"><span class="pre">qemu_event_wait</span></code> has acquire semantics.</li> </ul> <p>For example, in the following example there are no atomic accesses, but still thread 2 is relying on the <em>synchronizes-with</em> relation between <code class="docutils literal notranslate"><span class="pre">pthread_exit</span></code> (release) and <code class="docutils literal notranslate"><span class="pre">pthread_join</span></code> (acquire):</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="42%" /> <col width="58%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">thread 1</th> <th class="head">thread 2</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="o">*</span><span class="n">a</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">pthread_exit</span><span class="p">(</span><span class="n">a</span><span class="p">);</span> </pre></div> </div> </td> <td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">pthread_join</span><span class="p">(</span><span class="n">thread1</span><span class="p">,</span> <span class="o">&</span><span class="n">a</span><span class="p">);</span> <span class="n">x</span> <span class="o">=</span> <span class="o">*</span><span class="n">a</span><span class="p">;</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> <p>Synchronization between threads basically descends from this pairing of a release operation and an acquire operation. Therefore, atomic operations other than <code class="docutils literal notranslate"><span class="pre">qatomic_set()</span></code> and <code class="docutils literal notranslate"><span class="pre">qatomic_read()</span></code> will almost always be paired with another operation of the opposite kind: an acquire operation will pair with a release operation and vice versa. This rule of thumb is extremely useful; in the case of QEMU, however, note that the other operation may actually be in a driver that runs in the guest!</p> <p><code class="docutils literal notranslate"><span class="pre">smp_read_barrier_depends()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_rmb()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_mb_acquire()</span></code>, <code class="docutils literal notranslate"><span class="pre">qatomic_load_acquire()</span></code> and <code class="docutils literal notranslate"><span class="pre">qatomic_rcu_read()</span></code> all count as acquire operations. <code class="docutils literal notranslate"><span class="pre">smp_wmb()</span></code>, <code class="docutils literal notranslate"><span class="pre">smp_mb_release()</span></code>, <code class="docutils literal notranslate"><span class="pre">qatomic_store_release()</span></code> and <code class="docutils literal notranslate"><span class="pre">qatomic_rcu_set()</span></code> all count as release operations. <code class="docutils literal notranslate"><span class="pre">smp_mb()</span></code> counts as both acquire and release, therefore it can pair with any other atomic operation. Here is an example:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="42%" /> <col width="58%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">thread 1</th> <th class="head">thread 2</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">qatomic_set</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">smp_wmb</span><span class="p">();</span> <span class="n">qatomic_set</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span> </pre></div> </div> </td> <td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">);</span> <span class="n">smp_rmb</span><span class="p">();</span> <span class="n">y</span> <span class="o">=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">);</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> <p>Note that a load-store pair only counts if the two operations access the same variable: that is, a store-release on a variable <code class="docutils literal notranslate"><span class="pre">x</span></code> <em>synchronizes with</em> a load-acquire on a variable <code class="docutils literal notranslate"><span class="pre">x</span></code>, while a release barrier synchronizes with any acquire operation. The following example shows correct synchronization:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="50%" /> <col width="50%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">thread 1</th> <th class="head">thread 2</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">qatomic_set</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">qatomic_store_release</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span> </pre></div> </div> </td> <td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="n">qatomic_load_acquire</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">);</span> <span class="n">y</span> <span class="o">=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">);</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> <p>Acquire and release semantics of higher-level primitives can also be relied upon for the purpose of establishing the <em>synchronizes with</em> relation.</p> <p>Note that the “writing” thread is accessing the variables in the opposite order as the “reading” thread. This is expected: stores before a release operation will normally match the loads after the acquire operation, and vice versa. In fact, this happened already in the <code class="docutils literal notranslate"><span class="pre">pthread_exit</span></code>/<code class="docutils literal notranslate"><span class="pre">pthread_join</span></code> example above.</p> <p>Finally, this more complex example has more than two accesses and data dependency barriers. It also does not use atomic accesses whenever there cannot be a data race:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="42%" /> <col width="58%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">thread 1</th> <th class="head">thread 2</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">b</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">smp_wmb</span><span class="p">();</span> <span class="n">x</span><span class="o">-></span><span class="n">i</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="n">smp_wmb</span><span class="p">();</span> <span class="n">qatomic_set</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span> </pre></div> </div> </td> <td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">a</span><span class="p">);</span> <span class="n">smp_read_barrier_depends</span><span class="p">();</span> <span class="n">y</span> <span class="o">=</span> <span class="n">x</span><span class="o">-></span><span class="n">i</span><span class="p">;</span> <span class="n">smp_read_barrier_depends</span><span class="p">();</span> <span class="n">z</span> <span class="o">=</span> <span class="n">b</span><span class="p">[</span><span class="n">y</span><span class="p">];</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> </div> </div> <div class="section" id="comparison-with-linux-kernel-primitives"> <h2>Comparison with Linux kernel primitives<a class="headerlink" href="#comparison-with-linux-kernel-primitives" title="Permalink to this headline">¶</a></h2> <p>Here is a list of differences between Linux kernel atomic operations and memory barriers, and the equivalents in QEMU:</p> <ul> <li><p class="first">atomic operations in Linux are always on a 32-bit int type and use a boxed <code class="docutils literal notranslate"><span class="pre">atomic_t</span></code> type; atomic operations in QEMU are polymorphic and use normal C types.</p> </li> <li><p class="first">Originally, <code class="docutils literal notranslate"><span class="pre">atomic_read</span></code> and <code class="docutils literal notranslate"><span class="pre">atomic_set</span></code> in Linux gave no guarantee at all. Linux 4.1 updated them to implement volatile semantics via <code class="docutils literal notranslate"><span class="pre">ACCESS_ONCE</span></code> (or the more recent <code class="docutils literal notranslate"><span class="pre">READ</span></code>/<code class="docutils literal notranslate"><span class="pre">WRITE_ONCE</span></code>).</p> <p>QEMU’s <code class="docutils literal notranslate"><span class="pre">qatomic_read</span></code> and <code class="docutils literal notranslate"><span class="pre">qatomic_set</span></code> implement C11 atomic relaxed semantics if the compiler supports it, and volatile semantics otherwise. Both semantics prevent the compiler from doing certain transformations; the difference is that atomic accesses are guaranteed to be atomic, while volatile accesses aren’t. Thus, in the volatile case we just cross our fingers hoping that the compiler will generate atomic accesses, since we assume the variables passed are machine-word sized and properly aligned.</p> <p>No barriers are implied by <code class="docutils literal notranslate"><span class="pre">qatomic_read</span></code> and <code class="docutils literal notranslate"><span class="pre">qatomic_set</span></code> in either Linux or QEMU.</p> </li> <li><p class="first">atomic read-modify-write operations in Linux are of three kinds:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="34%" /> <col width="66%" /> </colgroup> <tbody valign="top"> <tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">atomic_OP</span></code></td> <td>returns void</td> </tr> <tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">atomic_OP_return</span></code></td> <td>returns new value of the variable</td> </tr> <tr class="row-odd"><td><code class="docutils literal notranslate"><span class="pre">atomic_fetch_OP</span></code></td> <td>returns the old value of the variable</td> </tr> <tr class="row-even"><td><code class="docutils literal notranslate"><span class="pre">atomic_cmpxchg</span></code></td> <td>returns the old value of the variable</td> </tr> </tbody> </table> </div></blockquote> <p>In QEMU, the second kind is named <code class="docutils literal notranslate"><span class="pre">atomic_OP_fetch</span></code>.</p> </li> <li><p class="first">different atomic read-modify-write operations in Linux imply a different set of memory barriers; in QEMU, all of them enforce sequential consistency.</p> </li> <li><p class="first">in QEMU, <code class="docutils literal notranslate"><span class="pre">qatomic_read()</span></code> and <code class="docutils literal notranslate"><span class="pre">qatomic_set()</span></code> do not participate in the ordering enforced by read-modify-write operations. This is because QEMU uses the C11 memory model. The following example is correct in Linux but not in QEMU:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="52%" /> <col width="48%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">Linux (correct)</th> <th class="head">QEMU (incorrect)</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="n">atomic_fetch_add</span><span class="p">(</span><span class="o">&</span><span class="n">x</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span> <span class="n">b</span> <span class="o">=</span> <span class="n">READ_ONCE</span><span class="p">(</span><span class="o">&</span><span class="n">y</span><span class="p">);</span> </pre></div> </div> </td> <td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="n">qatomic_fetch_add</span><span class="p">(</span><span class="o">&</span><span class="n">x</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span> <span class="n">b</span> <span class="o">=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">y</span><span class="p">);</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> <p>because the read of <code class="docutils literal notranslate"><span class="pre">y</span></code> can be moved (by either the processor or the compiler) before the write of <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p> <p>Fixing this requires a full memory barrier between the write of <code class="docutils literal notranslate"><span class="pre">x</span></code> and the read of <code class="docutils literal notranslate"><span class="pre">y</span></code>. QEMU provides <code class="docutils literal notranslate"><span class="pre">smp_mb__before_rmw()</span></code> and <code class="docutils literal notranslate"><span class="pre">smp_mb__after_rmw()</span></code>; they act both as an optimization, avoiding the memory barrier on processors where it is unnecessary, and as a clarification of this corner case of the C11 memory model:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="100%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">QEMU (correct)</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="n">qatomic_fetch_add</span><span class="p">(</span><span class="o">&</span><span class="n">x</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span> <span class="n">smp_mb__after_rmw</span><span class="p">();</span> <span class="n">b</span> <span class="o">=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">y</span><span class="p">);</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> <p>In the common case where only one thread writes <code class="docutils literal notranslate"><span class="pre">x</span></code>, it is also possible to write it like this:</p> <blockquote> <div><table border="1" class="docutils"> <colgroup> <col width="100%" /> </colgroup> <thead valign="bottom"> <tr class="row-odd"><th class="head">QEMU (correct)</th> </tr> </thead> <tbody valign="top"> <tr class="row-even"><td><div class="first last highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">a</span> <span class="o">=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">x</span><span class="p">);</span> <span class="n">qatomic_set</span><span class="p">(</span><span class="o">&</span><span class="n">x</span><span class="p">,</span> <span class="n">a</span> <span class="o">+</span> <span class="mi">2</span><span class="p">);</span> <span class="n">smp_mb</span><span class="p">();</span> <span class="n">b</span> <span class="o">=</span> <span class="n">qatomic_read</span><span class="p">(</span><span class="o">&</span><span class="n">y</span><span class="p">);</span> </pre></div> </div> </td> </tr> </tbody> </table> </div></blockquote> </li> </ul> </div> <div class="section" id="sources"> <h2>Sources<a class="headerlink" href="#sources" title="Permalink to this headline">¶</a></h2> <ul class="simple"> <li><code class="docutils literal notranslate"><span class="pre">Documentation/memory-barriers.txt</span></code> from the Linux kernel</li> </ul> </div> </div> </div> </div> <footer> <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation"> <a href="stable-process.html" class="btn btn-neutral float-right" title="QEMU and the stable process" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a> <a href="migration.html" class="btn btn-neutral" title="Migration" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a> </div> <hr/> <div role="contentinfo"> <p> © Copyright 2021, The QEMU Project Developers. </p> </div> Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>. <!-- Empty para to force a blank line after "Built with Sphinx ..." --> <p></p> <p>This documentation is for QEMU version 6.2.0.</p> <p><a href="../about/license.html">QEMU and this manual are released under the GNU General Public License, version 2.</a></p> </footer> </div> </div> </section> </div> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT:'../', VERSION:'qemu-kvm-6.2.0-53.module+el8.10.0+2055+8eb7870b.4', LANGUAGE:'None', COLLAPSE_INDEX:false, FILE_SUFFIX:'.html', HAS_SOURCE: false, SOURCELINK_SUFFIX: '.txt' }; </script> <script type="text/javascript" src="../_static/jquery.js"></script> <script type="text/javascript" src="../_static/underscore.js"></script> <script type="text/javascript" src="../_static/doctools.js"></script> <script type="text/javascript" src="../_static/js/theme.js"></script> <script type="text/javascript"> jQuery(function () { SphinxRtdTheme.Navigation.enable(true); }); </script> </body> </html>