title: Lock free single producer/single consumer circular buffer
body: <p>I have been looking at a lock free single producer/single consumer circular buffer on <a href="https://www.codeproject.com/articles/43510/lock-free-single-producer-single-consumer-circular" rel="noreferrer">this website</a> when I couldn't figure out why a specific memory barrier was needed.
  I have carefully read a hundread time <a href="https://en.cppreference.com/w/cpp/atomic/memory_order" rel="noreferrer">the standard rules about memory order</a> but I don't understand what I'm missing. </p>
  
  <p>With this implementation, there is only a unique thread which can call the <code>push()</code> function and another unique thread which can call the <code>pop()</code> function.</p>
  
  <p>Here is the <code>Producer</code> code:</p>
  
  <pre><code>bool push(const Element&amp; item)
  {       
    const auto current_tail = _tail.load(std::memory_order_relaxed);  //(1)
    const auto next_tail = increment(current_tail);
  
    if(next_tail != _head.load(std::memory_order_acquire))            //(2)               
    {     
      _array[current_tail] = item;                                    //(3)
      _tail.store(next_tail, std::memory_order_release);              //(4)
      return true;
    }
    return false; // full queue
  }
  </code></pre>
  
  <p>Here is the <code>Consumer</code> code:</p>
  
  <pre><code>bool pop(Element&amp; item)
  {
    const auto current_head = _head.load(std::memory_order_relaxed);    //(1)
    if(current_head == _tail.load(std::memory_order_acquire))           //(2)
      return false; // empty queue
  
    item = _array[current_head];                                       //(3)
    _head.store(increment(current_head), std::memory_order_release);   //(4)
    return true;
  }
  </code></pre>
  
  <p>I understand why the <code>Producer (4)</code> and the <code>Consumer (2)</code> statements are absolutly needed, this is because we have to make sure that all writes that <em>happened before</em> the <code>(4) released store</code> by the <code>Producer</code>will be visible side effects once the <code>consumer</code> will see the stored value.</p>
  
  <p>I also understand why the <code>Consumer (4)</code> statement is needed, this is to make sure that the <code>Consumer (3)</code> load will be performed before the <code>Consumer (4)</code> store will be performed.</p>
  
  <p><strong>The question</strong></p>
  
  <ul>
  <li>Why is the <code>Producer (2)</code> load needs to be performed with <em>acquire semantic</em> (instead of <em>relaxed</em>)? Is it to prevent <code>Producer (3) or (4)</code> to be reodered before the condition (at compile time or at runtime)?</li>
  </ul>