title: Using memory barriers to force in-order execution
body: <p>Trying to go on with my idea that using both software and hardware memory barriers I could disable the out-of-order optimization for a specific function inside a code that is compiled with compiler optimization, and therefore I could implement software semaphore using algorithms like <code>Peterson</code> or <code>Deker</code> that requires no out-of-order execution, I have tested the following code that contains both SW barrier <code>asm volatile("": : :"memory")</code> and gcc builtin HW barrier <code>__sync_synchronize</code>:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  int main(int argc, char ** argv)
  {
      int x=0;
      asm volatile("": : :"memory");
      __sync_synchronize();
      x=1;
      asm volatile("": : :"memory");
      __sync_synchronize();
      x=2;
      asm volatile("": : :"memory");
      __sync_synchronize();
      x=3;
      printf("%d",x);
      return 0;
  }
  </code></pre>
  
  <p>But the compilation output file is:</p>
  
  <pre><code>main:
  .LFB24:
      .cfi_startproc
      subq    $8, %rsp
      .cfi_def_cfa_offset 16
      mfence
      mfence
      movl    $3, %edx
      movl    $.LC0, %esi
      movl    $1, %edi
      xorl    %eax, %eax
      mfence
      call    __printf_chk
      xorl    %eax, %eax
      addq    $8, %rsp
  </code></pre>
  
  <p>And if I remove the barriers and compile again, I get:</p>
  
  <pre><code>main
  .LFB24:
      .cfi_startproc
      subq    $8, %rsp
      .cfi_def_cfa_offset 16
      movl    $3, %edx
      movl    $.LC0, %esi
      movl    $1, %edi
      xorl    %eax, %eax
      call    __printf_chk
      xorl    %eax, %eax
      addq    $8, %rsp
  </code></pre>
  
  <p>both compiled with <code>gcc -Wall -O2</code> in Ubuntu 14.04.1 LTS, x86.</p>
  
  <p>The expected result was that the output file of the code that contains the memory barriers will contain all the assignments of the values I have in my source code, with <code>mfence</code> between them.</p>
  
  <p>According to a related StackOverflow post - </p>
  
  <p><a href="https://stackoverflow.com/questions/19965076/gcc-memory-barrier-sync-synchronize-vs-asm-volatile-memory">gcc memory barrier __sync_synchronize vs asm volatile(&quot;&quot;: : :&quot;memory&quot;)</a></p>
  
  <blockquote>
    <p>When adding your inline assembly on each iteration, gcc is not permitted to change the order of the operations past the barrier</p>
  </blockquote>
  
  <p>And later on:</p>
  
  <blockquote>
    <p>However, when the CPU performes this code, it's permitted to reorder
    the operations "under the hood", as long as it does not break memory
    ordering model. This means that performing the operations can be done
    out of order (if the CPU supports that, as most do these days). A HW
    fence would have prevented that.</p>
  </blockquote>
  
  <p>But as you can see, the only difference between the code with the memory barriers and the code without them is that the former one contains <code>mfence</code> in a way I was not expected to see it, and not all the assignments are included.</p>
  
  <p>Why is the output file of the file with the memory barriers was not as I expected- Why does the <code>mfence</code> order has been altered? Why did the compiler remove some of the assignments? Is the compiler allowed to make such optimizations even if the memory barrier is applied and separates every single line of code?</p>
  
  <p>References to the memory barrier types and usage:</p>
  
  <ul>
  <li><p>Memory Barriers - <a href="http://bruceblinn.com/linuxinfo/MemoryBarriers.html" rel="nofollow noreferrer">http://bruceblinn.com/linuxinfo/MemoryBarriers.html</a></p></li>
  <li><p>GCC Builtins - <a href="https://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Atomic-Builtins.html" rel="nofollow noreferrer">https://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Atomic-Builtins.html</a></p></li>
  </ul>