From: Dmitry Vyukov Date: Wed, 17 Dec 2014 10:19:20 +0000 (+0000) Subject: tsan: add disabled test case for issue 87 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=508dd9b94c7c310a42982fae9b22fc21ebcdd482;p=platform%2Fupstream%2Fllvm.git tsan: add disabled test case for issue 87 llvm-svn: 224422 --- diff --git a/compiler-rt/test/tsan/stack_sync_reuse.cc b/compiler-rt/test/tsan/stack_sync_reuse.cc new file mode 100644 index 0000000..b1d5619 --- /dev/null +++ b/compiler-rt/test/tsan/stack_sync_reuse.cc @@ -0,0 +1,68 @@ +// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s +#include +#include +#include +#include + +// Test case https://code.google.com/p/thread-sanitizer/issues/detail?id=87 +// Tsan sees false HB edge on address pointed to by syncp variable. +// It is false because when acquire is done syncp points to a var in one frame, +// and during release it points to a var in a different frame. +// The code is somewhat tricky because it prevents compiler from optimizing +// our accesses away, structured to not introduce other data races and +// not introduce other synchronization, and to arrange the vars in different +// frames to occupy the same address. + +// The data race CHECK-NOT below actually must be CHECK, because the program +// does contain the data race on global. + +// CHECK-NOT: WARNING: ThreadSanitizer: data race +// CHECK: DONE + +long global; +long *syncp; +long *addr; +long sink; + +void *Thread(void *x) { + while (__atomic_load_n(&syncp, __ATOMIC_ACQUIRE) == 0) + usleep(1000); + global = 42; + __atomic_store_n(syncp, 1, __ATOMIC_RELEASE); + __atomic_store_n(&syncp, 0, __ATOMIC_RELAXED); + return NULL; +} + +void __attribute__((noinline)) foobar() { + long s; + addr = &s; + __atomic_store_n(&s, 0, __ATOMIC_RELAXED); + __atomic_store_n(&syncp, &s, __ATOMIC_RELEASE); + while (__atomic_load_n(&syncp, __ATOMIC_RELAXED) != 0) + usleep(1000); +} + +void __attribute__((noinline)) barfoo() { + long s; + if (addr != &s) { + printf("address mismatch addr=%p &s=%p\n", addr, &s); + exit(1); + } + __atomic_store_n(&addr, &s, __ATOMIC_RELAXED); + __atomic_store_n(&s, 0, __ATOMIC_RELAXED); + sink = __atomic_load_n(&s, __ATOMIC_ACQUIRE); + global = 43; +} + +int main() { + pthread_t t; + pthread_create(&t, 0, Thread, 0); + foobar(); + barfoo(); + pthread_join(t, 0); + if (sink != 0) + exit(1); + fprintf(stderr, "DONE\n"); + return 0; +} +