1 2 #include <pthread.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 6 /* Simple test program, no race. Parent and child both modify x and 7 use the hardware bus lock. */ 8 9 #undef PLAT_x86_darwin 10 #undef PLAT_amd64_darwin 11 #undef PLAT_x86_linux 12 #undef PLAT_amd64_linux 13 #undef PLAT_ppc32_linux 14 #undef PLAT_ppc64_linux 15 #undef PLAT_arm_linux 16 #undef PLAT_s390x_linux 17 #undef PLAT_mips32_linux 18 19 #if defined(__APPLE__) && defined(__i386__) 20 # define PLAT_x86_darwin 1 21 #elif defined(__APPLE__) && defined(__x86_64__) 22 # define PLAT_amd64_darwin 1 23 #elif defined(__linux__) && defined(__i386__) 24 # define PLAT_x86_linux 1 25 #elif defined(__linux__) && defined(__x86_64__) 26 # define PLAT_amd64_linux 1 27 #elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) 28 # define PLAT_ppc32_linux 1 29 #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) 30 # define PLAT_ppc64_linux 1 31 #elif defined(__linux__) && defined(__arm__) 32 # define PLAT_arm_linux 1 33 #elif defined(__linux__) && defined(__s390x__) 34 # define PLAT_s390x_linux 1 35 #elif defined(__linux__) && defined(__mips__) 36 # define PLAT_mips32_linux 1 37 #endif 38 39 #if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) \ 40 || defined(PLAT_amd64_darwin) || defined(PLAT_x86_darwin) 41 # define INC(_lval,_lqual) \ 42 __asm__ __volatile__ ( \ 43 "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" ) 44 #elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) 45 # define INC(_lval,_lqual) \ 46 __asm__ __volatile__( \ 47 "1:\n" \ 48 " lwarx 15,0,%0\n" \ 49 " addi 15,15,1\n" \ 50 " stwcx. 15,0,%0\n" \ 51 " bne- 1b\n" \ 52 : /*out*/ : /*in*/ "b"(&(_lval)) \ 53 : /*trash*/ "r15", "cr0", "memory" \ 54 ) 55 #elif defined(PLAT_arm_linux) 56 # define INC(_lval,_lqual) \ 57 __asm__ __volatile__( \ 58 "1:\n" \ 59 " ldrex r8, [%0, #0]\n" \ 60 " add r8, r8, #1\n" \ 61 " strex r9, r8, [%0, #0]\n" \ 62 " cmp r9, #0\n" \ 63 " bne 1b\n" \ 64 : /*out*/ : /*in*/ "r"(&(_lval)) \ 65 : /*trash*/ "r8", "r9", "cc", "memory" \ 66 ); 67 #elif defined(PLAT_s390x_linux) 68 # define INC(_lval,_lqual) \ 69 __asm__ __volatile__( \ 70 "1: l 0,%0\n" \ 71 " lr 1,0\n" \ 72 " ahi 1,1\n" \ 73 " cs 0,1,%0\n" \ 74 " jl 1b\n" \ 75 : "+m" (_lval) :: "cc", "1","2" \ 76 ) 77 #elif defined(PLAT_mips32_linux) 78 # define INC(_lval,_lqual) \ 79 __asm__ __volatile__ ( \ 80 "1:\n" \ 81 " move $8, %0\n" \ 82 " ll $9, 0($8)\n" \ 83 " addiu $9, $9, 1\n" \ 84 " sc $9, 0($8)\n" \ 85 " li $10, 1\n" \ 86 " bne $9, $10, 1b\n" \ 87 " nop\n" \ 88 : /*out*/ : /*in*/ "r"(&(_lval)) \ 89 : /*trash*/ "$8", "$9", "$10", "cc", "memory" \ 90 ) 91 #else 92 # error "Fix Me for this platform" 93 #endif 94 95 96 int x = 0; 97 98 void* child_fn ( void* arg ) 99 { 100 INC(x, "childfn"); 101 return NULL; 102 } 103 104 int main ( void ) 105 { 106 pthread_t child; 107 108 if (pthread_create(&child, NULL, child_fn, NULL)) { 109 perror("pthread_create"); 110 exit(1); 111 } 112 113 INC(x, "main"); 114 115 if (pthread_join(child, NULL)) { 116 perror("pthread join"); 117 exit(1); 118 } 119 120 printf("x = %d\n", x); 121 return 0; 122 } 123