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_x86_darwin
     10 #undef PLAT_amd64_darwin
     11 #undef PLAT_x86_linux
     12 #undef PLAT_amd64_linux
     13 #undef PLAT_ppc32_linux
     14 #undef PLAT_ppc64_linux
     15 #undef PLAT_arm_linux
     16 #undef PLAT_s390x_linux
     17 
     18 #if defined(__APPLE__) && defined(__i386__)
     19 #  define PLAT_x86_darwin 1
     20 #elif defined(__APPLE__) && defined(__x86_64__)
     21 #  define PLAT_amd64_darwin 1
     22 #elif defined(__linux__) && defined(__i386__)
     23 #  define PLAT_x86_linux 1
     24 #elif defined(__linux__) && defined(__x86_64__)
     25 #  define PLAT_amd64_linux 1
     26 #elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
     27 #  define PLAT_ppc32_linux 1
     28 #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
     29 #  define PLAT_ppc64_linux 1
     30 #elif defined(__linux__) && defined(__arm__)
     31 #  define PLAT_arm_linux 1
     32 #elif defined(__linux__) && defined(__s390x__)
     33 #  define PLAT_s390x_linux 1
     34 #endif
     35 
     36 #if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) \
     37     || defined(PLAT_amd64_darwin) || defined(PLAT_x86_darwin)
     38 #  define INC(_lval,_lqual) \
     39       __asm__ __volatile__ ( \
     40       "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" )
     41 #elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux)
     42 #  define INC(_lval,_lqual)               \
     43    __asm__ __volatile__(                  \
     44       "1:\n"                              \
     45       "        lwarx 15,0,%0\n"           \
     46       "        addi 15,15,1\n"            \
     47       "        stwcx. 15,0,%0\n"          \
     48       "        bne- 1b\n"                 \
     49       : /*out*/ : /*in*/ "b"(&(_lval))    \
     50       : /*trash*/ "r15", "cr0", "memory"  \
     51    )
     52 #elif defined(PLAT_arm_linux)
     53 #  define INC(_lval,_lqual) \
     54   __asm__ __volatile__( \
     55       "1:\n"                                 \
     56       "        ldrex r8, [%0, #0]\n"         \
     57       "        add   r8, r8, #1\n"           \
     58       "        strex r9, r8, [%0, #0]\n"     \
     59       "        cmp   r9, #0\n"               \
     60       "        bne   1b\n"                   \
     61       : /*out*/ : /*in*/ "r"(&(_lval))       \
     62       : /*trash*/ "r8", "r9", "cc", "memory" \
     63   );
     64 #elif defined(PLAT_s390x_linux)
     65 #  define INC(_lval,_lqual) \
     66    __asm__ __volatile__( \
     67       "1: l     0,%0\n"                            \
     68       "   lr    1,0\n"                             \
     69       "   ahi   1,1\n"                             \
     70       "   cs    0,1,%0\n"                          \
     71       "   jl    1b\n"                              \
     72       : "+m" (_lval) :: "cc", "1","2" \
     73    )
     74 #else
     75 #  error "Fix Me for this platform"
     76 #endif
     77 
     78 
     79 int x = 0;
     80 
     81 void* child_fn ( void* arg )
     82 {
     83    INC(x, "childfn");
     84    return NULL;
     85 }
     86 
     87 int main ( void )
     88 {
     89    pthread_t child;
     90 
     91    if (pthread_create(&child, NULL, child_fn, NULL)) {
     92       perror("pthread_create");
     93       exit(1);
     94    }
     95 
     96    INC(x, "main");
     97 
     98    if (pthread_join(child, NULL)) {
     99       perror("pthread join");
    100       exit(1);
    101    }
    102 
    103    printf("x = %d\n", x);
    104    return 0;
    105 }
    106