title: C++11 memory_order_acquire and memory_order_release semantics?
body: <p><a href="http://en.cppreference.com/w/cpp/atomic/memory_order" rel="noreferrer">http://en.cppreference.com/w/cpp/atomic/memory_order</a>, and other C++11 online references, define memory_order_acquire and memory_order_release as:</p>
  
  <ul>
  <li>Acquire operation: no <strong>reads</strong> in the current thread can be reordered before this load.</li>
  <li>Release operation: no <strong>writes</strong> in the current thread can be reordered after this store.</li>
  </ul>
  
  <p>This seems to allow post-acquire-writes to be executed <strong>before</strong> the acquire operation, which seems weird too me (usual acquire/release operation semantics restrict movement of <strong>all</strong> memory operations).</p>
  
  <p>Same online source (<a href="http://en.cppreference.com/w/cpp/atomic/atomic_flag" rel="noreferrer">http://en.cppreference.com/w/cpp/atomic/atomic_flag</a>) suggests that a spinlock mutex can be built using C++ atomics and the above mentioned relaxed memory ordering rules:</p>
  
  <pre><code>lock mutex: while (lock.test_and_set(std::memory_order_acquire))
  
  unlock mutex: lock.clear(std::memory_order_release);               
  </code></pre>
  
  <p>With this definition of lock/unlock, wouldn't the simple code below be broken if memory_order_acquire/release are indeed defined this way (i.e., not forbidding reordering of post-acquire-writes):</p>
  
  <pre><code>Thread1:
    (0) lock
      (1) x = 1;
      (2) if (x != 1) PANIC
    (3) unlock
  
  Thread2:
    (4) lock
      (5) x = 0;
    (6) unlock
  </code></pre>
  
  <p>Is the following execution possible: (0) lock, (1) x = 1, (5) x = 0, (2) PANIC ? What did I miss?</p>