1b411202f9ff33a587558e2e836626bc7eb9db183sewardj 2b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <pthread.h> 3b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <stdio.h> 4b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <stdlib.h> 5b411202f9ff33a587558e2e836626bc7eb9db183sewardj 6b411202f9ff33a587558e2e836626bc7eb9db183sewardj/* Simple test program, no race. Parent and child both modify x and 7b411202f9ff33a587558e2e836626bc7eb9db183sewardj use the hardware bus lock. */ 8b411202f9ff33a587558e2e836626bc7eb9db183sewardj 98777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_x86_darwin 108777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_amd64_darwin 11b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_x86_linux 12b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_amd64_linux 13b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_ppc32_linux 14b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_ppc64_linux 158777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_arm_linux 1623ed6302e96eb905ef25d6c39db600e17e5f341fsewardj#undef PLAT_arm64_linux 17b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#undef PLAT_s390x_linux 185db15403e889d4db339b342bc2a824ef0bfaa654sewardj#undef PLAT_mips32_linux 19112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#undef PLAT_tilegx_linux 208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#undef PLAT_x86_solaris 218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#undef PLAT_amd64_solaris 22b411202f9ff33a587558e2e836626bc7eb9db183sewardj 236e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#if defined(__APPLE__) && defined(__i386__) 248777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_x86_darwin 1 258777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__APPLE__) && defined(__x86_64__) 268777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_amd64_darwin 1 278777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__i386__) 28b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_x86_linux 1 298777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__x86_64__) 30b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_amd64_linux 1 318777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) 32b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_ppc32_linux 1 338777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) 34b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_ppc64_linux 1 3523ed6302e96eb905ef25d6c39db600e17e5f341fsewardj#elif defined(__linux__) && defined(__arm__) && !defined(__aarch64__) 368777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_arm_linux 1 3723ed6302e96eb905ef25d6c39db600e17e5f341fsewardj#elif defined(__linux__) && defined(__aarch64__) && !defined(__arm__) 3823ed6302e96eb905ef25d6c39db600e17e5f341fsewardj# define PLAT_arm64_linux 1 39b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(__linux__) && defined(__s390x__) 40b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# define PLAT_s390x_linux 1 415db15403e889d4db339b342bc2a824ef0bfaa654sewardj#elif defined(__linux__) && defined(__mips__) 425db15403e889d4db339b342bc2a824ef0bfaa654sewardj# define PLAT_mips32_linux 1 43112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(__linux__) && defined(__tilegx__) 44112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# define PLAT_tilegx_linux 1 458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(__sun__) && defined(__i386__) 468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# define PLAT_x86_solaris 1 478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(__sun__) && defined(__x86_64__) 488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# define PLAT_amd64_solaris 1 49b411202f9ff33a587558e2e836626bc7eb9db183sewardj#endif 50b411202f9ff33a587558e2e836626bc7eb9db183sewardj 51f5b5f84a476b54c239a5179de49728b6fa8f3b85sewardj#if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) \ 528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj || defined(PLAT_amd64_darwin) || defined(PLAT_x86_darwin) \ 538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj || defined(PLAT_amd64_solaris) || defined(PLAT_x86_solaris) 542ee33955b80812a8f31ec06a0430103b50aeca8csewardj# define INC(_lval,_lqual) \ 55b411202f9ff33a587558e2e836626bc7eb9db183sewardj __asm__ __volatile__ ( \ 56b411202f9ff33a587558e2e836626bc7eb9db183sewardj "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" ) 576e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) 582ee33955b80812a8f31ec06a0430103b50aeca8csewardj# define INC(_lval,_lqual) \ 59b411202f9ff33a587558e2e836626bc7eb9db183sewardj __asm__ __volatile__( \ 60d12c4a53875f9280323784227b0af727c7991966sewardj "1:\n" \ 61b411202f9ff33a587558e2e836626bc7eb9db183sewardj " lwarx 15,0,%0\n" \ 62b411202f9ff33a587558e2e836626bc7eb9db183sewardj " addi 15,15,1\n" \ 63b411202f9ff33a587558e2e836626bc7eb9db183sewardj " stwcx. 15,0,%0\n" \ 64d12c4a53875f9280323784227b0af727c7991966sewardj " bne- 1b\n" \ 65b411202f9ff33a587558e2e836626bc7eb9db183sewardj : /*out*/ : /*in*/ "b"(&(_lval)) \ 66b411202f9ff33a587558e2e836626bc7eb9db183sewardj : /*trash*/ "r15", "cr0", "memory" \ 67b411202f9ff33a587558e2e836626bc7eb9db183sewardj ) 688777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(PLAT_arm_linux) 698777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define INC(_lval,_lqual) \ 708777f7308785b4eb67898670e29ecdde42dec9dfsewardj __asm__ __volatile__( \ 71d12c4a53875f9280323784227b0af727c7991966sewardj "1:\n" \ 728777f7308785b4eb67898670e29ecdde42dec9dfsewardj " ldrex r8, [%0, #0]\n" \ 738777f7308785b4eb67898670e29ecdde42dec9dfsewardj " add r8, r8, #1\n" \ 748777f7308785b4eb67898670e29ecdde42dec9dfsewardj " strex r9, r8, [%0, #0]\n" \ 758777f7308785b4eb67898670e29ecdde42dec9dfsewardj " cmp r9, #0\n" \ 76d12c4a53875f9280323784227b0af727c7991966sewardj " bne 1b\n" \ 778777f7308785b4eb67898670e29ecdde42dec9dfsewardj : /*out*/ : /*in*/ "r"(&(_lval)) \ 788777f7308785b4eb67898670e29ecdde42dec9dfsewardj : /*trash*/ "r8", "r9", "cc", "memory" \ 798777f7308785b4eb67898670e29ecdde42dec9dfsewardj ); 8023ed6302e96eb905ef25d6c39db600e17e5f341fsewardj#elif defined(PLAT_arm64_linux) 8123ed6302e96eb905ef25d6c39db600e17e5f341fsewardj# define INC(_lval,_lqual) \ 8223ed6302e96eb905ef25d6c39db600e17e5f341fsewardj __asm__ __volatile__( \ 8323ed6302e96eb905ef25d6c39db600e17e5f341fsewardj "1:\n" \ 8423ed6302e96eb905ef25d6c39db600e17e5f341fsewardj " ldxr w8, [%0, #0]\n" \ 8523ed6302e96eb905ef25d6c39db600e17e5f341fsewardj " add w8, w8, #1\n" \ 8623ed6302e96eb905ef25d6c39db600e17e5f341fsewardj " stxr w9, w8, [%0, #0]\n" \ 8723ed6302e96eb905ef25d6c39db600e17e5f341fsewardj " cmp w9, #0\n" \ 8823ed6302e96eb905ef25d6c39db600e17e5f341fsewardj " bne 1b\n" \ 8923ed6302e96eb905ef25d6c39db600e17e5f341fsewardj : /*out*/ : /*in*/ "r"(&(_lval)) \ 9023ed6302e96eb905ef25d6c39db600e17e5f341fsewardj : /*trash*/ "x8", "x9", "cc", "memory" \ 9123ed6302e96eb905ef25d6c39db600e17e5f341fsewardj ); 92b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(PLAT_s390x_linux) 93b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# define INC(_lval,_lqual) \ 94b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj __asm__ __volatile__( \ 95b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj "1: l 0,%0\n" \ 96b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj " lr 1,0\n" \ 97b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj " ahi 1,1\n" \ 98b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj " cs 0,1,%0\n" \ 99b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj " jl 1b\n" \ 100b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj : "+m" (_lval) :: "cc", "1","2" \ 101b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj ) 1025db15403e889d4db339b342bc2a824ef0bfaa654sewardj#elif defined(PLAT_mips32_linux) 1035db15403e889d4db339b342bc2a824ef0bfaa654sewardj# define INC(_lval,_lqual) \ 1045db15403e889d4db339b342bc2a824ef0bfaa654sewardj __asm__ __volatile__ ( \ 1055db15403e889d4db339b342bc2a824ef0bfaa654sewardj "1:\n" \ 1065db15403e889d4db339b342bc2a824ef0bfaa654sewardj " move $8, %0\n" \ 1075db15403e889d4db339b342bc2a824ef0bfaa654sewardj " ll $9, 0($8)\n" \ 1085db15403e889d4db339b342bc2a824ef0bfaa654sewardj " addiu $9, $9, 1\n" \ 1095db15403e889d4db339b342bc2a824ef0bfaa654sewardj " sc $9, 0($8)\n" \ 1105db15403e889d4db339b342bc2a824ef0bfaa654sewardj " li $10, 1\n" \ 1115db15403e889d4db339b342bc2a824ef0bfaa654sewardj " bne $9, $10, 1b\n" \ 1125db15403e889d4db339b342bc2a824ef0bfaa654sewardj " nop\n" \ 1135db15403e889d4db339b342bc2a824ef0bfaa654sewardj : /*out*/ : /*in*/ "r"(&(_lval)) \ 1145db15403e889d4db339b342bc2a824ef0bfaa654sewardj : /*trash*/ "$8", "$9", "$10", "cc", "memory" \ 1155db15403e889d4db339b342bc2a824ef0bfaa654sewardj ) 116112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(PLAT_tilegx_linux) 117112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# define INC(_lval,_lqual) \ 118112711afefcfcd43680c7c4aa8d38ef180e8811esewardj if (sizeof(_lval) == 4) \ 119112711afefcfcd43680c7c4aa8d38ef180e8811esewardj __insn_fetchadd(&(_lval), 1); \ 120112711afefcfcd43680c7c4aa8d38ef180e8811esewardj else if(sizeof(_lval) == 8) \ 121112711afefcfcd43680c7c4aa8d38ef180e8811esewardj __insn_fetchadd(&(_lval), 1) 122b411202f9ff33a587558e2e836626bc7eb9db183sewardj#else 123b411202f9ff33a587558e2e836626bc7eb9db183sewardj# error "Fix Me for this platform" 124b411202f9ff33a587558e2e836626bc7eb9db183sewardj#endif 125b411202f9ff33a587558e2e836626bc7eb9db183sewardj 126b411202f9ff33a587558e2e836626bc7eb9db183sewardj 127b411202f9ff33a587558e2e836626bc7eb9db183sewardjint x = 0; 128b411202f9ff33a587558e2e836626bc7eb9db183sewardj 129b411202f9ff33a587558e2e836626bc7eb9db183sewardjvoid* child_fn ( void* arg ) 130b411202f9ff33a587558e2e836626bc7eb9db183sewardj{ 1312ee33955b80812a8f31ec06a0430103b50aeca8csewardj INC(x, "childfn"); 132b411202f9ff33a587558e2e836626bc7eb9db183sewardj return NULL; 133b411202f9ff33a587558e2e836626bc7eb9db183sewardj} 134b411202f9ff33a587558e2e836626bc7eb9db183sewardj 135b411202f9ff33a587558e2e836626bc7eb9db183sewardjint main ( void ) 136b411202f9ff33a587558e2e836626bc7eb9db183sewardj{ 137b411202f9ff33a587558e2e836626bc7eb9db183sewardj pthread_t child; 138b411202f9ff33a587558e2e836626bc7eb9db183sewardj 139b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (pthread_create(&child, NULL, child_fn, NULL)) { 140b411202f9ff33a587558e2e836626bc7eb9db183sewardj perror("pthread_create"); 141b411202f9ff33a587558e2e836626bc7eb9db183sewardj exit(1); 142b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 143b411202f9ff33a587558e2e836626bc7eb9db183sewardj 1442ee33955b80812a8f31ec06a0430103b50aeca8csewardj INC(x, "main"); 145b411202f9ff33a587558e2e836626bc7eb9db183sewardj 146b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (pthread_join(child, NULL)) { 147b411202f9ff33a587558e2e836626bc7eb9db183sewardj perror("pthread join"); 148b411202f9ff33a587558e2e836626bc7eb9db183sewardj exit(1); 149b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 150b411202f9ff33a587558e2e836626bc7eb9db183sewardj 151b411202f9ff33a587558e2e836626bc7eb9db183sewardj printf("x = %d\n", x); 152b411202f9ff33a587558e2e836626bc7eb9db183sewardj return 0; 153b411202f9ff33a587558e2e836626bc7eb9db183sewardj} 154