Home | History | Annotate | Download | only in tests
      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_ppc64_aix5
     10 #undef PLAT_ppc32_aix5
     11 #undef PLAT_x86_darwin
     12 #undef PLAT_amd64_darwin
     13 #undef PLAT_x86_linux
     14 #undef PLAT_amd64_linux
     15 #undef PLAT_ppc32_linux
     16 #undef PLAT_ppc64_linux
     17 #undef PLAT_arm_linux
     18 
     19 #if defined(_AIX) && defined(__64BIT__)
     20 #  define PLAT_ppc64_aix5 1
     21 #elif defined(_AIX) && !defined(__64BIT__)
     22 #  define PLAT_ppc32_aix5 1
     23 #elif 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__)
     36 #  define PLAT_arm_linux 1
     37 #endif
     38 
     39 #if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) \
     40     || defined(PLAT_amd64_darwin) || defined(PLAT_x86_darwin)
     41 #  define INC(_lval,_lqual) \
     42       __asm__ __volatile__ ( \
     43       "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" )
     44 #elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) \
     45       || defined(PLAT_ppc32_aix5) || defined(PLAT_ppc64_aix5)
     46 #  define INC(_lval,_lqual)               \
     47    __asm__ __volatile__(                  \
     48       "L1xyzzy1" _lqual ":\n"             \
     49       "        lwarx 15,0,%0\n"           \
     50       "        addi 15,15,1\n"            \
     51       "        stwcx. 15,0,%0\n"          \
     52       "        bne- L1xyzzy1" _lqual      \
     53       : /*out*/ : /*in*/ "b"(&(_lval))    \
     54       : /*trash*/ "r15", "cr0", "memory"  \
     55    )
     56 #elif defined(PLAT_arm_linux)
     57 #  define INC(_lval,_lqual) \
     58   __asm__ __volatile__( \
     59       "L1xyzzy1" _lqual ":\n"                \
     60       "        ldrex r8, [%0, #0]\n"         \
     61       "        add   r8, r8, #1\n"           \
     62       "        strex r9, r8, [%0, #0]\n"     \
     63       "        cmp   r9, #0\n"               \
     64       "        bne L1xyzzy1" _lqual          \
     65       : /*out*/ : /*in*/ "r"(&(_lval))       \
     66       : /*trash*/ "r8", "r9", "cc", "memory" \
     67   );
     68 #else
     69 #  error "Fix Me for this platform"
     70 #endif
     71 
     72 
     73 int x = 0;
     74 
     75 void* child_fn ( void* arg )
     76 {
     77    INC(x, "childfn");
     78    return NULL;
     79 }
     80 
     81 int main ( void )
     82 {
     83    pthread_t child;
     84 
     85    if (pthread_create(&child, NULL, child_fn, NULL)) {
     86       perror("pthread_create");
     87       exit(1);
     88    }
     89 
     90    INC(x, "main");
     91 
     92    if (pthread_join(child, NULL)) {
     93       perror("pthread join");
     94       exit(1);
     95    }
     96 
     97    printf("x = %d\n", x);
     98    return 0;
     99 }
    100