title: why user space atomic_t in gcc(3.4.5) doesn't work
body: <p>Recently in my work, I want to implement a counter in a multi-thread program. I find there is a user space data type named <strong>atomic_t</strong> in my GCC(3.4.5). But it seems not real atomic.   </p>
  
  <p>I tested <strong>atomic_inc()/atomic_read()</strong> on a x86_64 machine with 12 cores and linux kernel is 2.6.9.   </p>
  
  <p>This is the demo. I add pthread_cond_t and pthread_cond_broadcast to increase the degree of concurrency.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;stdint.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;asm/atomic.h&gt;
  
  atomic_t atomic_count;
  pthread_cond_t g_cond;
  pthread_mutex_t g_mutex;
  
  void* thread_func(void*p) {
      pthread_mutex_t* lock = (pthread_mutex_t*)p;
      pthread_mutex_lock(lock);
      pthread_cond_wait(&amp;g_cond, lock);
      pthread_mutex_unlock(lock);
  
      for (int i=0;i&lt;20000;++i){
          atomic_inc(&amp;atomic_count);
      }
      return NULL;
  }
  #define THRD_NUM 15
  
  int main() {
      atomic_set(&amp;atomic_count, 0);
      pthread_cond_init(&amp;g_cond, NULL);
      pthread_mutex_init(&amp;g_mutex, NULL);
      pthread_t pid[THRD_NUM];
  
      for (int i=0; i&lt;THRD_NUM; i++) {
          pthread_create(&amp;pid[i], NULL, thread_func, &amp;g_mutex);
      }
  
      sleep(3);
      pthread_cond_broadcast(&amp;g_cond);
  
      for (int i=0; i&lt;THRD_NUM; i++) {
          pthread_join(pid[i], NULL);
      }
  
      long ans = atomic_read(&amp;atomic_count);
      printf("atomic_count:%ld \n", ans);
  }
  </code></pre>
  
  <p>The expected result is 300000, but we always get 270000+ or 280000+ instead. 
  I found the implementation of <strong>atomic_inc()</strong> is  </p>
  
  <pre><code> static __inline__ void atomic_inc(atomic_t *v)
   {
       __asm__ __volatile__(
           LOCK "incl %0"
           :"=m" (v-&gt;counter)
           :"m" (v-&gt;counter));
   }
  </code></pre>
  
  <p>According to intel manual, the <em>LOCK</em> prefix has the semantic of full barrier. Is that means the program's output has nothing to do with instruction reorder?  </p>
  
  <p>What is more, I found an interesting phenomenon. If I set the <strong>THRD_NUM</strong> less then 12(my machine's core number), the error will be in less frequency. I think it may be caused by context switch. But I have no idea how this happened. Can someone help me? Thanks!</p>