First look at the test code
// cas.c#include <stdio.h>#include <pthread.h>#include <stdlib.h>static int count = 0;void *test_func(void *arg){ int i=0; for(i=0;i<100000;++i){ __sync_fetch_and_add(&count,1); } return NULL;}int main(int argc, const char *argv[]){ pthread_t id[100]; int i = 0; for(i=0;i<100;++i){ pthread_create(&id[i],NULL,test_func,NULL); } for(i=0;i<100;++i){ pthread_join(id[i],NULL); } printf("%d\n",count); return 0;}
// spinlock.c#include <stdio.h>#include <pthread.h>#include <stdlib.h>static int count = 0;static pthread_spinlock_t spinlock;void *test_func(void *arg){ int i=0; for(i=0;i<100000;++i){ pthread_spin_lock (&spinlock); count++; pthread_spin_unlock(&spinlock); } return NULL;}int main(int argc, const char *argv[]){ pthread_t id[100]; int i = 0; pthread_spin_init (&spinlock, 0); for(i=0;i<100;++i){ pthread_create(&id[i],NULL,test_func,NULL); } for(i=0;i<100;++i){ pthread_join(id[i],NULL); } printf("%d\n",count); return 0;}
// mutex.c #include <stdio.h>#include <pthread.h>#include <stdlib.h>static int count = 0;static pthread_mutex_t mutex;void *test_func(void *arg){ int i=0; for(i=0;i<100000;++i){ pthread_mutex_lock (&mutex); count++; pthread_mutex_unlock(&mutex); } return NULL;}int main(int argc, const char *argv[]){ pthread_t id[100]; int i = 0; pthread_mutex_init (&mutex,NULL); for(i=0;i<100;++i){ pthread_create(&id[i],NULL,test_func,NULL); } for(i=0;i<100;++i){ pthread_join(id[i],NULL); } printf("%d\n",count); return 0;}
Result:
# time ./mutex 10000000real 0m0.235suser 0m0.040ssys 0m0.000s# time ./spinlock 10000000real 0m0.111suser 0m0.010ssys 0m0.010s# time ./cas 10000000real 0m0.083suser 0m0.010ssys 0m0.000s
More gcc-provided atomic operation reference http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html