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_arm64_linux 17 #undef PLAT_s390x_linux 18 #undef PLAT_mips32_linux 19 #undef PLAT_tilegx_linux 20 #undef PLAT_x86_solaris 21 #undef PLAT_amd64_solaris 22 23 #if defined(__APPLE__) && defined(__i386__) 24 # define PLAT_x86_darwin 1 25 #elif defined(__APPLE__) && defined(__x86_64__) 26 # define PLAT_amd64_darwin 1 27 #elif defined(__linux__) && defined(__i386__) 28 # define PLAT_x86_linux 1 29 #elif defined(__linux__) && defined(__x86_64__) 30 # define PLAT_amd64_linux 1 31 #elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) 32 # define PLAT_ppc32_linux 1 33 #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) 34 # define PLAT_ppc64_linux 1 35 #elif defined(__linux__) && defined(__arm__) && !defined(__aarch64__) 36 # define PLAT_arm_linux 1 37 #elif defined(__linux__) && defined(__aarch64__) && !defined(__arm__) 38 # define PLAT_arm64_linux 1 39 #elif defined(__linux__) && defined(__s390x__) 40 # define PLAT_s390x_linux 1 41 #elif defined(__linux__) && defined(__mips__) 42 # define PLAT_mips32_linux 1 43 #elif defined(__linux__) && defined(__tilegx__) 44 # define PLAT_tilegx_linux 1 45 #elif defined(__sun__) && defined(__i386__) 46 # define PLAT_x86_solaris 1 47 #elif defined(__sun__) && defined(__x86_64__) 48 # define PLAT_amd64_solaris 1 49 #endif 50 51 #if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) \ 52 || defined(PLAT_amd64_darwin) || defined(PLAT_x86_darwin) \ 53 || defined(PLAT_amd64_solaris) || defined(PLAT_x86_solaris) 54 # define INC(_lval,_lqual) \ 55 __asm__ __volatile__ ( \ 56 "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" ) 57 #elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) 58 # define INC(_lval,_lqual) \ 59 __asm__ __volatile__( \ 60 "1:\n" \ 61 " lwarx 15,0,%0\n" \ 62 " addi 15,15,1\n" \ 63 " stwcx. 15,0,%0\n" \ 64 " bne- 1b\n" \ 65 : /*out*/ : /*in*/ "b"(&(_lval)) \ 66 : /*trash*/ "r15", "cr0", "memory" \ 67 ) 68 #elif defined(PLAT_arm_linux) 69 # define INC(_lval,_lqual) \ 70 __asm__ __volatile__( \ 71 "1:\n" \ 72 " ldrex r8, [%0, #0]\n" \ 73 " add r8, r8, #1\n" \ 74 " strex r9, r8, [%0, #0]\n" \ 75 " cmp r9, #0\n" \ 76 " bne 1b\n" \ 77 : /*out*/ : /*in*/ "r"(&(_lval)) \ 78 : /*trash*/ "r8", "r9", "cc", "memory" \ 79 ); 80 #elif defined(PLAT_arm64_linux) 81 # define INC(_lval,_lqual) \ 82 __asm__ __volatile__( \ 83 "1:\n" \ 84 " ldxr w8, [%0, #0]\n" \ 85 " add w8, w8, #1\n" \ 86 " stxr w9, w8, [%0, #0]\n" \ 87 " cmp w9, #0\n" \ 88 " bne 1b\n" \ 89 : /*out*/ : /*in*/ "r"(&(_lval)) \ 90 : /*trash*/ "x8", "x9", "cc", "memory" \ 91 ); 92 #elif defined(PLAT_s390x_linux) 93 # define INC(_lval,_lqual) \ 94 __asm__ __volatile__( \ 95 "1: l 0,%0\n" \ 96 " lr 1,0\n" \ 97 " ahi 1,1\n" \ 98 " cs 0,1,%0\n" \ 99 " jl 1b\n" \ 100 : "+m" (_lval) :: "cc", "1","2" \ 101 ) 102 #elif defined(PLAT_mips32_linux) 103 # define INC(_lval,_lqual) \ 104 __asm__ __volatile__ ( \ 105 "1:\n" \ 106 " move $8, %0\n" \ 107 " ll $9, 0($8)\n" \ 108 " addiu $9, $9, 1\n" \ 109 " sc $9, 0($8)\n" \ 110 " li $10, 1\n" \ 111 " bne $9, $10, 1b\n" \ 112 " nop\n" \ 113 : /*out*/ : /*in*/ "r"(&(_lval)) \ 114 : /*trash*/ "$8", "$9", "$10", "cc", "memory" \ 115 ) 116 #elif defined(PLAT_tilegx_linux) 117 # define INC(_lval,_lqual) \ 118 if (sizeof(_lval) == 4) \ 119 __insn_fetchadd(&(_lval), 1); \ 120 else if(sizeof(_lval) == 8) \ 121 __insn_fetchadd(&(_lval), 1) 122 #else 123 # error "Fix Me for this platform" 124 #endif 125 126 127 int x = 0; 128 129 void* child_fn ( void* arg ) 130 { 131 INC(x, "childfn"); 132 return NULL; 133 } 134 135 int main ( void ) 136 { 137 pthread_t child; 138 139 if (pthread_create(&child, NULL, child_fn, NULL)) { 140 perror("pthread_create"); 141 exit(1); 142 } 143 144 INC(x, "main"); 145 146 if (pthread_join(child, NULL)) { 147 perror("pthread join"); 148 exit(1); 149 } 150 151 printf("x = %d\n", x); 152 return 0; 153 } 154