Using memory barriers to force in-order execution
<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>