tc08_hbl2.c revision 8777f7308785b4eb67898670e29ecdde42dec9df
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_ppc64_aix5 268777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_ppc32_aix5 278777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_x86_darwin 288777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_amd64_darwin 29b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_x86_linux 30b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_amd64_linux 31b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_ppc32_linux 32b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_ppc64_linux 338777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_arm_linux 34b411202f9ff33a587558e2e836626bc7eb9db183sewardj 358777f7308785b4eb67898670e29ecdde42dec9dfsewardj#if defined(_AIX) && defined(__64BIT__) 368777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_ppc64_aix5 1 378777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(_AIX) && !defined(__64BIT__) 388777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_ppc32_aix5 1 398777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__APPLE__) && defined(__i386__) 408777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_x86_darwin 1 418777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__APPLE__) && defined(__x86_64__) 428777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_amd64_darwin 1 438777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__i386__) 44b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_x86_linux 1 458777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__x86_64__) 46b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_amd64_linux 1 478777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__) 48b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_ppc32_linux 1 498777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) 50b411202f9ff33a587558e2e836626bc7eb9db183sewardj# define PLAT_ppc64_linux 1 518777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__arm__) 528777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define PLAT_arm_linux 1 53b411202f9ff33a587558e2e836626bc7eb9db183sewardj#endif 54b411202f9ff33a587558e2e836626bc7eb9db183sewardj 558777f7308785b4eb67898670e29ecdde42dec9dfsewardj 56b411202f9ff33a587558e2e836626bc7eb9db183sewardj#if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) 572ee33955b80812a8f31ec06a0430103b50aeca8csewardj# define INC(_lval,_lqual) \ 58b411202f9ff33a587558e2e836626bc7eb9db183sewardj __asm__ __volatile__ ( \ 59b411202f9ff33a587558e2e836626bc7eb9db183sewardj "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" ) 602ee33955b80812a8f31ec06a0430103b50aeca8csewardj#elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) \ 612ee33955b80812a8f31ec06a0430103b50aeca8csewardj || defined(PLAT_ppc32_aix5) || defined(PLAT_ppc64_aix5) 622ee33955b80812a8f31ec06a0430103b50aeca8csewardj# define INC(_lval,_lqual) \ 63b411202f9ff33a587558e2e836626bc7eb9db183sewardj __asm__ __volatile__( \ 642ee33955b80812a8f31ec06a0430103b50aeca8csewardj "L1xyzzy1" _lqual ":\n" \ 65b411202f9ff33a587558e2e836626bc7eb9db183sewardj " lwarx 15,0,%0\n" \ 66b411202f9ff33a587558e2e836626bc7eb9db183sewardj " addi 15,15,1\n" \ 67b411202f9ff33a587558e2e836626bc7eb9db183sewardj " stwcx. 15,0,%0\n" \ 682ee33955b80812a8f31ec06a0430103b50aeca8csewardj " bne- L1xyzzy1" _lqual \ 69b411202f9ff33a587558e2e836626bc7eb9db183sewardj : /*out*/ : /*in*/ "b"(&(_lval)) \ 70b411202f9ff33a587558e2e836626bc7eb9db183sewardj : /*trash*/ "r15", "cr0", "memory" \ 71b411202f9ff33a587558e2e836626bc7eb9db183sewardj ) 728777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(PLAT_arm_linux) 738777f7308785b4eb67898670e29ecdde42dec9dfsewardj# define INC(_lval,_lqual) \ 748777f7308785b4eb67898670e29ecdde42dec9dfsewardj __asm__ __volatile__( \ 758777f7308785b4eb67898670e29ecdde42dec9dfsewardj "L1xyzzy1" _lqual ":\n" \ 768777f7308785b4eb67898670e29ecdde42dec9dfsewardj " ldrex r8, [%0, #0]\n" \ 778777f7308785b4eb67898670e29ecdde42dec9dfsewardj " add r8, r8, #1\n" \ 788777f7308785b4eb67898670e29ecdde42dec9dfsewardj " strex r9, r8, [%0, #0]\n" \ 798777f7308785b4eb67898670e29ecdde42dec9dfsewardj " cmp r9, #0\n" \ 808777f7308785b4eb67898670e29ecdde42dec9dfsewardj " bne L1xyzzy1" _lqual \ 818777f7308785b4eb67898670e29ecdde42dec9dfsewardj : /*out*/ : /*in*/ "r"(&(_lval)) \ 828777f7308785b4eb67898670e29ecdde42dec9dfsewardj : /*trash*/ "r8", "r9", "cc", "memory" \ 838777f7308785b4eb67898670e29ecdde42dec9dfsewardj ); 84b411202f9ff33a587558e2e836626bc7eb9db183sewardj#else 85b411202f9ff33a587558e2e836626bc7eb9db183sewardj# error "Fix Me for this platform" 86b411202f9ff33a587558e2e836626bc7eb9db183sewardj#endif 87b411202f9ff33a587558e2e836626bc7eb9db183sewardj 88b411202f9ff33a587558e2e836626bc7eb9db183sewardj 89b411202f9ff33a587558e2e836626bc7eb9db183sewardj 90b411202f9ff33a587558e2e836626bc7eb9db183sewardj#define LIMIT 10 91b411202f9ff33a587558e2e836626bc7eb9db183sewardj 92b411202f9ff33a587558e2e836626bc7eb9db183sewardjvolatile int x = 0; 93b411202f9ff33a587558e2e836626bc7eb9db183sewardj 94b411202f9ff33a587558e2e836626bc7eb9db183sewardjvoid* child_fn ( void* arg ) 95b411202f9ff33a587558e2e836626bc7eb9db183sewardj{ 96b411202f9ff33a587558e2e836626bc7eb9db183sewardj int q = 0; 97b411202f9ff33a587558e2e836626bc7eb9db183sewardj int oldx = 0; 98b411202f9ff33a587558e2e836626bc7eb9db183sewardj int ctr = 0; 99b411202f9ff33a587558e2e836626bc7eb9db183sewardj while (1) { 100b411202f9ff33a587558e2e836626bc7eb9db183sewardj q = (x >= LIMIT); 101b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (x != oldx) { 102b411202f9ff33a587558e2e836626bc7eb9db183sewardj oldx = x; 103b411202f9ff33a587558e2e836626bc7eb9db183sewardj printf("child: new value %d\n", oldx); 104b411202f9ff33a587558e2e836626bc7eb9db183sewardj fflush(stdout); 105b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 106b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (q) break; 107b411202f9ff33a587558e2e836626bc7eb9db183sewardj /* Make sure the parent doesn't starve. Seems to be a problem 108b411202f9ff33a587558e2e836626bc7eb9db183sewardj on very slow machines. */ 109b411202f9ff33a587558e2e836626bc7eb9db183sewardj ctr++; 110b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (ctr == 2000000) sleep(1); 111b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 112b411202f9ff33a587558e2e836626bc7eb9db183sewardj return NULL; 113b411202f9ff33a587558e2e836626bc7eb9db183sewardj} 114b411202f9ff33a587558e2e836626bc7eb9db183sewardj 115b411202f9ff33a587558e2e836626bc7eb9db183sewardjint main ( void ) 116b411202f9ff33a587558e2e836626bc7eb9db183sewardj{ 117b411202f9ff33a587558e2e836626bc7eb9db183sewardj pthread_t child; 118b411202f9ff33a587558e2e836626bc7eb9db183sewardj int i; 119b411202f9ff33a587558e2e836626bc7eb9db183sewardj 120b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (pthread_create(&child, NULL, child_fn, NULL)) { 121b411202f9ff33a587558e2e836626bc7eb9db183sewardj perror("pthread_create"); 122b411202f9ff33a587558e2e836626bc7eb9db183sewardj exit(1); 123b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 124b411202f9ff33a587558e2e836626bc7eb9db183sewardj 125b411202f9ff33a587558e2e836626bc7eb9db183sewardj for (i = 0; i < LIMIT; i++) { 1262ee33955b80812a8f31ec06a0430103b50aeca8csewardj INC(x, "main"); 127b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (i == 5) sleep(1); /* make sure child doesn't starve */ 128b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 129b411202f9ff33a587558e2e836626bc7eb9db183sewardj 130b411202f9ff33a587558e2e836626bc7eb9db183sewardj if (pthread_join(child, NULL)) { 131b411202f9ff33a587558e2e836626bc7eb9db183sewardj perror("pthread join"); 132b411202f9ff33a587558e2e836626bc7eb9db183sewardj exit(1); 133b411202f9ff33a587558e2e836626bc7eb9db183sewardj } 134b411202f9ff33a587558e2e836626bc7eb9db183sewardj 135b411202f9ff33a587558e2e836626bc7eb9db183sewardj printf("done, x = %d\n", x); 136b411202f9ff33a587558e2e836626bc7eb9db183sewardj 137b411202f9ff33a587558e2e836626bc7eb9db183sewardj return 0; 138b411202f9ff33a587558e2e836626bc7eb9db183sewardj} 139