title: ARM64: LDXR/STXR vs LDAXR/STLXR
body: <p>On iOS, there are two similar functions, <code>OSAtomicAdd32</code> and <code>OSAtomicAdd32Barrier</code>. I'm wondering when you would need the <code>Barrier</code> variant.</p>
  
  <p>Disassembled, they are:</p>
  
  <pre><code>_OSAtomicAdd32:
  ldxr    w8, [x1]
  add     w8, w8, w0
  stxr    w9, w8, [x1]
  cbnz    w9, _OSAtomicAdd32
  mov     x0, x8
  ret     lr
  
  _OSAtomicAdd32Barrier:
  ldaxr   w8, [x1]
  add     w8, w8, w0
  stlxr   w9, w8, [x1]
  cbnz    w9, _OSAtomicAdd32Barrier
  mov     x0, x8
  ret     lr
  </code></pre>
  
  <p>In which scenarios would you need the Load-Acquire / Store-Release semantics of the latter? Can <code>LDXR</code>/<code>STXR</code> instructions be reordered? If they can, is it possible for an atomic update to be "lost" in the absence of a barrier? From what I've read, it doesn't seem like that can happen, and if true, then why would you need the <code>Barrier</code> variant? Perhaps only if you also happened to need a <code>DMB</code> for other purposes?</p>
  
  <p>Thanks!</p>