diff options
Diffstat (limited to 'helgrind/tests/.svn/text-base/tc08_hbl2.c.svn-base')
-rw-r--r-- | helgrind/tests/.svn/text-base/tc08_hbl2.c.svn-base | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/helgrind/tests/.svn/text-base/tc08_hbl2.c.svn-base b/helgrind/tests/.svn/text-base/tc08_hbl2.c.svn-base new file mode 100644 index 0000000..d67435a --- /dev/null +++ b/helgrind/tests/.svn/text-base/tc08_hbl2.c.svn-base @@ -0,0 +1,117 @@ + +/* FIXME: this is basically a bad test as it is scheduling- + sensitive. Sometimes the output is: + + child: new value 6 + child: new value 10 + done, x = 10 + + and sometimes + + child: new value 10 + done, x = 10 +*/ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +/* Simple test program, no race. Parent writes atomically to a counter + whilst child reads it. When counter reaches a prearranged value, + child joins back to parent. Parent (writer) uses hardware bus lock; + child is only reading and so does not need to use a bus lock. */ + + +#undef PLAT_x86_linux +#undef PLAT_amd64_linux +#undef PLAT_ppc32_linux +#undef PLAT_ppc64_linux +#undef PLAT_ppc32_aix5 +#undef PLAT_ppc64_aix5 + +#if !defined(_AIX) && defined(__i386__) +# define PLAT_x86_linux 1 +#elif !defined(_AIX) && defined(__x86_64__) +# define PLAT_amd64_linux 1 +#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__) +# define PLAT_ppc32_linux 1 +#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__) +# define PLAT_ppc64_linux 1 +#elif defined(_AIX) && defined(__64BIT__) +# define PLAT_ppc64_aix5 1 +#elif defined(_AIX) && !defined(__64BIT__) +# define PLAT_ppc32_aix5 1 +#endif + +#if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux) +# define INC(_lval,_lqual) \ + __asm__ __volatile__ ( \ + "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" ) +#elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) \ + || defined(PLAT_ppc32_aix5) || defined(PLAT_ppc64_aix5) +# define INC(_lval,_lqual) \ + __asm__ __volatile__( \ + "L1xyzzy1" _lqual ":\n" \ + " lwarx 15,0,%0\n" \ + " addi 15,15,1\n" \ + " stwcx. 15,0,%0\n" \ + " bne- L1xyzzy1" _lqual \ + : /*out*/ : /*in*/ "b"(&(_lval)) \ + : /*trash*/ "r15", "cr0", "memory" \ + ) +#else +# error "Fix Me for this platform" +#endif + + + +#define LIMIT 10 + +volatile int x = 0; + +void* child_fn ( void* arg ) +{ + int q = 0; + int oldx = 0; + int ctr = 0; + while (1) { + q = (x >= LIMIT); + if (x != oldx) { + oldx = x; + printf("child: new value %d\n", oldx); + fflush(stdout); + } + if (q) break; + /* Make sure the parent doesn't starve. Seems to be a problem + on very slow machines. */ + ctr++; + if (ctr == 2000000) sleep(1); + } + return NULL; +} + +int main ( void ) +{ + pthread_t child; + int i; + + if (pthread_create(&child, NULL, child_fn, NULL)) { + perror("pthread_create"); + exit(1); + } + + for (i = 0; i < LIMIT; i++) { + INC(x, "main"); + if (i == 5) sleep(1); /* make sure child doesn't starve */ + } + + if (pthread_join(child, NULL)) { + perror("pthread join"); + exit(1); + } + + printf("done, x = %d\n", x); + + return 0; +} |