tc08_hbl2.c revision 112711afefcfcd43680c7c4aa8d38ef180e8811e
1b411202f9ff33a587558e2e836626bc7eb9db183sewardj 2b411202f9ff33a587558e2e836626bc7eb9db183sewardj/* FIXME: this is basically a bad test as it is scheduling- 3b411202f9ff33a587558e2e836626bc7eb9db183sewardj sensitive. Sometimes the output is: 4b411202f9ff33a587558e2e836626bc7eb9db183sewardj 5b411202f9ff33a587558e2e836626bc7eb9db183sewardj child: new value 6 6b411202f9ff33a587558e2e836626bc7eb9db183sewardj child: new value 10 7b411202f9ff33a587558e2e836626bc7eb9db183sewardj done, x = 10 8b411202f9ff33a587558e2e836626bc7eb9db183sewardj 9b411202f9ff33a587558e2e836626bc7eb9db183sewardj and sometimes 10b411202f9ff33a587558e2e836626bc7eb9db183sewardj 11b411202f9ff33a587558e2e836626bc7eb9db183sewardj child: new value 10 12b411202f9ff33a587558e2e836626bc7eb9db183sewardj done, x = 10 13b411202f9ff33a587558e2e836626bc7eb9db183sewardj*/ 14b411202f9ff33a587558e2e836626bc7eb9db183sewardj 15b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <pthread.h> 16b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <stdio.h> 17b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <stdlib.h> 18b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <unistd.h> 19b411202f9ff33a587558e2e836626bc7eb9db183sewardj 20b411202f9ff33a587558e2e836626bc7eb9db183sewardj/* Simple test program, no race. Parent writes atomically to a counter 21b411202f9ff33a587558e2e836626bc7eb9db183sewardj whilst child reads it. When counter reaches a prearranged value, 22b411202f9ff33a587558e2e836626bc7eb9db183sewardj child joins back to parent. Parent (writer) uses hardware bus lock; 23b411202f9ff33a587558e2e836626bc7eb9db183sewardj child is only reading and so does not need to use a bus lock. */ 24b411202f9ff33a587558e2e836626bc7eb9db183sewardj 258777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_x86_darwin 268777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_amd64_darwin 27b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_x86_linux 28b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_amd64_linux 29b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_ppc32_linux 30b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_ppc64_linux 318777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_arm_linux 3223ed6302e96eb905ef25d6c39db600e17e5f341fsewardj#undef PLAT_arm64_linux 33b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#undef PLAT_s390x_linux 345db15403e889d4db339b342bc2a824ef0bfaa654sewardj#undef PLAT_mips32_linux 35d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj#undef PLAT_mips64_linux 36112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#undef PLAT_tilegx_linux 37b411202f9ff33a587558e2e836626bc7eb9db183sewardj 386e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#if defined(__APPLE__) && defined(__i386__) 398777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_x86_darwin 1 408777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__APPLE__) && defined(__x86_64__) 418777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_amd64_darwin 1 428777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__i386__) 43b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_x86_linux 1 448777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__x86_64__) 45b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_amd64_linux 1 468777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) 47b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_ppc32_linux 1 488777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) 49b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_ppc64_linux 1 5023ed6302e96eb905ef25d6c39db600e17e5f341fsewardj#elif defined(__linux__) && defined(__arm__) && !defined(__aarch64__) 518777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_arm_linux 1 5223ed6302e96eb905ef25d6c39db600e17e5f341fsewardj#elif defined(__linux__) && defined(__aarch64__) && !defined(__arm__) 5323ed6302e96eb905ef25d6c39db600e17e5f341fsewardj# define PLAT_arm64_linux 1 54b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(__linux__) && defined(__s390x__) 55b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# define PLAT_s390x_linux 1 565db15403e889d4db339b342bc2a824ef0bfaa654sewardj#elif defined(__linux__) && defined(__mips__) 57d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj#if (__mips==64) 58d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj# define PLAT_mips64_linux 1 59d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj#else 605db15403e889d4db339b342bc2a824ef0bfaa654sewardj# define PLAT_mips32_linux 1 61b411202f9ff33a587558e2e836626bc7eb9db183sewardj#endif 62112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(__linux__) && defined(__tilegx__) 63112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# define PLAT_tilegx_linux 1 64d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj#endif 65b411202f9ff33a587558e2e836626bc7eb9db183sewardj 668777f7308785b4eb67898670e29ecdde42dec9dfsewardj 67f5b5f84a476b54c239a5179de49728b6fa8f3b85sewardj#if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) \ 68f5b5f84a476b54c239a5179de49728b6fa8f3b85sewardj || defined(PLAT_amd64_darwin) || defined(PLAT_x86_darwin) 692ee33955b80812a8f31ec06a0430103b50aeca8csewardj# define INC(_lval,_lqual) \ 70b411202f9ff33a587558e2e836626bc7eb9db183sewardj __asm__ __volatile__ ( \ 71b411202f9ff33a587558e2e836626bc7eb9db183sewardj "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" ) 726e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj#elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) 732ee33955b80812a8f31ec06a0430103b50aeca8csewardj# define INC(_lval,_lqual) \ 74b411202f9ff33a587558e2e836626bc7eb9db183sewardj __asm__ __volatile__( \ 75d12c4a53875f9280323784227b0af727c7991966sewardj "1:\n" \ 76b411202f9ff33a587558e2e836626bc7eb9db183sewardj " lwarx 15,0,%0\n" \ 77b411202f9ff33a587558e2e836626bc7eb9db183sewardj " addi 15,15,1\n" \ 78b411202f9ff33a587558e2e836626bc7eb9db183sewardj " stwcx. 15,0,%0\n" \ 79d12c4a53875f9280323784227b0af727c7991966sewardj " bne- 1b\n" \ 80b411202f9ff33a587558e2e836626bc7eb9db183sewardj : /*out*/ : /*in*/ "b"(&(_lval)) \ 81b411202f9ff33a587558e2e836626bc7eb9db183sewardj : /*trash*/ "r15", "cr0", "memory" \ 82b411202f9ff33a587558e2e836626bc7eb9db183sewardj ) 838777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(PLAT_arm_linux) 848777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define INC(_lval,_lqual) \ 858777f7308785b4eb67898670e29ecdde42dec9dfsewardj __asm__ __volatile__( \ 86d12c4a53875f9280323784227b0af727c7991966sewardj "1:\n" \ 878777f7308785b4eb67898670e29ecdde42dec9dfsewardj " ldrex r8, [%0, #0]\n" \ 888777f7308785b4eb67898670e29ecdde42dec9dfsewardj " add r8, r8, #1\n" \ 898777f7308785b4eb67898670e29ecdde42dec9dfsewardj " strex r9, r8, [%0, #0]\n" \ 908777f7308785b4eb67898670e29ecdde42dec9dfsewardj " cmp r9, #0\n" \ 91d12c4a53875f9280323784227b0af727c7991966sewardj " bne 1b\n" \ 928777f7308785b4eb67898670e29ecdde42dec9dfsewardj : /*out*/ : /*in*/ "r"(&(_lval)) \ 938777f7308785b4eb67898670e29ecdde42dec9dfsewardj : /*trash*/ "r8", "r9", "cc", "memory" \ 948777f7308785b4eb67898670e29ecdde42dec9dfsewardj ); 9523ed6302e96eb905ef25d6c39db600e17e5f341fsewardj#elif defined(PLAT_arm64_linux) 9623ed6302e96eb905ef25d6c39db600e17e5f341fsewardj# define INC(_lval,_lqual) \ 9723ed6302e96eb905ef25d6c39db600e17e5f341fsewardj __asm__ __volatile__( \ 9823ed6302e96eb905ef25d6c39db600e17e5f341fsewardj "1:\n" \ 9923ed6302e96eb905ef25d6c39db600e17e5f341fsewardj " ldxr w8, [%0, #0]\n" \ 10023ed6302e96eb905ef25d6c39db600e17e5f341fsewardj " add w8, w8, #1\n" \ 10123ed6302e96eb905ef25d6c39db600e17e5f341fsewardj " stxr w9, w8, [%0, #0]\n" \ 10223ed6302e96eb905ef25d6c39db600e17e5f341fsewardj " cmp w9, #0\n" \ 10323ed6302e96eb905ef25d6c39db600e17e5f341fsewardj " bne 1b\n" \ 10423ed6302e96eb905ef25d6c39db600e17e5f341fsewardj : /*out*/ : /*in*/ "r"(&(_lval)) \ 10523ed6302e96eb905ef25d6c39db600e17e5f341fsewardj : /*trash*/ "x8", "x9", "cc", "memory" \ 10623ed6302e96eb905ef25d6c39db600e17e5f341fsewardj ); 107b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(PLAT_s390x_linux) 108b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# define INC(_lval,_lqual) \ 109b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj __asm__ __volatile__( \ 110b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj "1: l 0,%0\n" \ 111b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj " lr 1,0\n" \ 112b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj " ahi 1,1\n" \ 113b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj " cs 0,1,%0\n" \ 114b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj " jl 1b\n" \ 115b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj : "+m" (_lval) :: "cc", "0","1" \ 116b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj ) 117d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj#elif defined(PLAT_mips32_linux) || defined(PLAT_mips64_linux) 1185db15403e889d4db339b342bc2a824ef0bfaa654sewardj# define INC(_lval,_lqual) \ 1195db15403e889d4db339b342bc2a824ef0bfaa654sewardj __asm__ __volatile__ ( \ 1205db15403e889d4db339b342bc2a824ef0bfaa654sewardj "L1xyzzy1" _lqual":\n" \ 121d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj " move $t0, %0\n" \ 122d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj " ll $t1, 0($t0)\n" \ 123d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj " addi $t1, $t1, 1\n" \ 124d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj " sc $t1, 0($t0)\n" \ 125d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj " beqz $t1, L1xyzzy1" _lqual \ 1265db15403e889d4db339b342bc2a824ef0bfaa654sewardj : /*out*/ : /*in*/ "r"(&(_lval)) \ 127d5f0d1e2ae84afae0ef5c1db0fa1089280f0e3c9petarj : /*trash*/ "t0", "t1", "memory" \ 1285db15403e889d4db339b342bc2a824ef0bfaa654sewardj ) 129112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(PLAT_tilegx_linux) 130112711afefcfcd43680c7c4aa8d38ef180e8811esewardj# define INC(_lval,_lqual) \ 131112711afefcfcd43680c7c4aa8d38ef180e8811esewardj if (sizeof(_lval) == 4) \ 132112711afefcfcd43680c7c4aa8d38ef180e8811esewardj __insn_fetchadd(&(_lval), 1); \ 133112711afefcfcd43680c7c4aa8d38ef180e8811esewardj else if(sizeof(_lval) == 8) \ 134112711afefcfcd43680c7c4aa8d38ef180e8811esewardj __insn_fetchadd(&(_lval), 1) 135b411202f9ff33a587558e2e836626bc7eb9db183sewardj#else 136b411202f9ff33a587558e2e836626bc7eb9db183sewardj# error "Fix Me for this platform" 137b411202f9ff33a587558e2e836626bc7eb9db183sewardj#endif 138b411202f9ff33a587558e2e836626bc7eb9db183sewardj 139b411202f9ff33a587558e2e836626bc7eb9db183sewardj 140b411202f9ff33a587558e2e836626bc7eb9db183sewardj 141b411202f9ff33a587558e2e836626bc7eb9db183sewardj#define LIMIT 10 142b411202f9ff33a587558e2e836626bc7eb9db183sewardj 143b411202f9ff33a587558e2e836626bc7eb9db183sewardjvolatile int x = 0; 144b411202f9ff33a587558e2e836626bc7eb9db183sewardj 145b411202f9ff33a587558e2e836626bc7eb9db183sewardjvoid* child_fn ( void* arg ) 146b411202f9ff33a587558e2e836626bc7eb9db183sewardj{ 147b411202f9ff33a587558e2e836626bc7eb9db183sewardj int q = 0; 148b411202f9ff33a587558e2e836626bc7eb9db183sewardj int oldx = 0; 149f91fd73d264a38f0c742bd2eeb9895daa880aa5abart struct timespec ts = { 0, 1000 * 1000 }; 150f91fd73d264a38f0c742bd2eeb9895daa880aa5abart 151b411202f9ff33a587558e2e836626bc7eb9db183sewardj while (1) { 152b411202f9ff33a587558e2e836626bc7eb9db183sewardj q = (x >= LIMIT); 153b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (x != oldx) { 154b411202f9ff33a587558e2e836626bc7eb9db183sewardj oldx = x; 155b411202f9ff33a587558e2e836626bc7eb9db183sewardj printf("child: new value %d\n", oldx); 156b411202f9ff33a587558e2e836626bc7eb9db183sewardj fflush(stdout); 157b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 158b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (q) break; 159f91fd73d264a38f0c742bd2eeb9895daa880aa5abart nanosleep(&ts, 0); 160b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 161b411202f9ff33a587558e2e836626bc7eb9db183sewardj return NULL; 162b411202f9ff33a587558e2e836626bc7eb9db183sewardj} 163b411202f9ff33a587558e2e836626bc7eb9db183sewardj 164b411202f9ff33a587558e2e836626bc7eb9db183sewardjint main ( void ) 165b411202f9ff33a587558e2e836626bc7eb9db183sewardj{ 166b411202f9ff33a587558e2e836626bc7eb9db183sewardj pthread_t child; 167b411202f9ff33a587558e2e836626bc7eb9db183sewardj int i; 168b411202f9ff33a587558e2e836626bc7eb9db183sewardj 169b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (pthread_create(&child, NULL, child_fn, NULL)) { 170b411202f9ff33a587558e2e836626bc7eb9db183sewardj perror("pthread_create"); 171b411202f9ff33a587558e2e836626bc7eb9db183sewardj exit(1); 172b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 173b411202f9ff33a587558e2e836626bc7eb9db183sewardj 174b411202f9ff33a587558e2e836626bc7eb9db183sewardj for (i = 0; i < LIMIT; i++) { 1752ee33955b80812a8f31ec06a0430103b50aeca8csewardj INC(x, "main"); 176b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (i == 5) sleep(1); /* make sure child doesn't starve */ 177b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 178b411202f9ff33a587558e2e836626bc7eb9db183sewardj 179b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (pthread_join(child, NULL)) { 180b411202f9ff33a587558e2e836626bc7eb9db183sewardj perror("pthread join"); 181b411202f9ff33a587558e2e836626bc7eb9db183sewardj exit(1); 182b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 183b411202f9ff33a587558e2e836626bc7eb9db183sewardj 184b411202f9ff33a587558e2e836626bc7eb9db183sewardj printf("done, x = %d\n", x); 185b411202f9ff33a587558e2e836626bc7eb9db183sewardj 186b411202f9ff33a587558e2e836626bc7eb9db183sewardj return 0; 187b411202f9ff33a587558e2e836626bc7eb9db183sewardj} 188