sewardj | b411202 | 2007-11-09 22:49:28 +0000 | [diff] [blame] | 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_linux |
| 10 | #undef PLAT_amd64_linux |
| 11 | #undef PLAT_ppc32_linux |
| 12 | #undef PLAT_ppc64_linux |
| 13 | #undef PLAT_ppc32_aix5 |
| 14 | #undef PLAT_ppc64_aix5 |
| 15 | |
| 16 | #if !defined(_AIX) && defined(__i386__) |
| 17 | # define PLAT_x86_linux 1 |
| 18 | #elif !defined(_AIX) && defined(__x86_64__) |
| 19 | # define PLAT_amd64_linux 1 |
| 20 | #elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__) |
| 21 | # define PLAT_ppc32_linux 1 |
| 22 | #elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__) |
| 23 | # define PLAT_ppc64_linux 1 |
| 24 | #elif defined(_AIX) && defined(__64BIT__) |
| 25 | # define PLAT_ppc64_aix5 1 |
| 26 | #elif defined(_AIX) && !defined(__64BIT__) |
| 27 | # define PLAT_ppc32_aix5 1 |
| 28 | #endif |
| 29 | |
sewardj | b411202 | 2007-11-09 22:49:28 +0000 | [diff] [blame] | 30 | #if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) |
sewardj | 2ee3395 | 2007-11-27 11:23:55 +0000 | [diff] [blame] | 31 | # define INC(_lval,_lqual) \ |
sewardj | b411202 | 2007-11-09 22:49:28 +0000 | [diff] [blame] | 32 | __asm__ __volatile__ ( \ |
| 33 | "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" ) |
sewardj | 2ee3395 | 2007-11-27 11:23:55 +0000 | [diff] [blame] | 34 | #elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) \ |
| 35 | || defined(PLAT_ppc32_aix5) || defined(PLAT_ppc64_aix5) |
| 36 | # define INC(_lval,_lqual) \ |
sewardj | b411202 | 2007-11-09 22:49:28 +0000 | [diff] [blame] | 37 | __asm__ __volatile__( \ |
sewardj | 2ee3395 | 2007-11-27 11:23:55 +0000 | [diff] [blame] | 38 | "L1xyzzy1" _lqual ":\n" \ |
sewardj | b411202 | 2007-11-09 22:49:28 +0000 | [diff] [blame] | 39 | " lwarx 15,0,%0\n" \ |
| 40 | " addi 15,15,1\n" \ |
| 41 | " stwcx. 15,0,%0\n" \ |
sewardj | 2ee3395 | 2007-11-27 11:23:55 +0000 | [diff] [blame] | 42 | " bne- L1xyzzy1" _lqual \ |
sewardj | b411202 | 2007-11-09 22:49:28 +0000 | [diff] [blame] | 43 | : /*out*/ : /*in*/ "b"(&(_lval)) \ |
| 44 | : /*trash*/ "r15", "cr0", "memory" \ |
| 45 | ) |
| 46 | #else |
| 47 | # error "Fix Me for this platform" |
| 48 | #endif |
| 49 | |
| 50 | |
| 51 | int x = 0; |
| 52 | |
| 53 | void* child_fn ( void* arg ) |
| 54 | { |
sewardj | 2ee3395 | 2007-11-27 11:23:55 +0000 | [diff] [blame] | 55 | INC(x, "childfn"); |
sewardj | b411202 | 2007-11-09 22:49:28 +0000 | [diff] [blame] | 56 | return NULL; |
| 57 | } |
| 58 | |
| 59 | int main ( void ) |
| 60 | { |
| 61 | pthread_t child; |
| 62 | |
| 63 | if (pthread_create(&child, NULL, child_fn, NULL)) { |
| 64 | perror("pthread_create"); |
| 65 | exit(1); |
| 66 | } |
| 67 | |
sewardj | 2ee3395 | 2007-11-27 11:23:55 +0000 | [diff] [blame] | 68 | INC(x, "main"); |
sewardj | b411202 | 2007-11-09 22:49:28 +0000 | [diff] [blame] | 69 | |
| 70 | if (pthread_join(child, NULL)) { |
| 71 | perror("pthread join"); |
| 72 | exit(1); |
| 73 | } |
| 74 | |
| 75 | printf("x = %d\n", x); |
| 76 | return 0; |
| 77 | } |