Files
clang-p2996/compiler-rt/test/tsan/stack_sync_reuse.cc
Kuba Brecka 6c9122ffba [tsan] Change comments referencing code.google.com to point to GitHub instead. NFC.
Changing comments that have references to code.google.com to point to GitHub instead, because the current links are not redirected properly (they instead redirect to different issues, mostly ASan). NFC.

Differential Revision: http://reviews.llvm.org/D15053

llvm-svn: 254300
2015-11-30 14:11:48 +00:00

68 lines
1.9 KiB
C++

// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "test.h"
// Test case https://github.com/google/sanitizers/issues/494
// 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); // spin wait
global = 42;
__atomic_store_n(syncp, 1, __ATOMIC_RELEASE);
__atomic_store_n(&syncp, 0, __ATOMIC_RELAXED);
return NULL;
}
void __attribute__((noinline)) foobar() {
__attribute__((aligned(64))) 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); // spin wait
}
void __attribute__((noinline)) barfoo() {
__attribute__((aligned(64))) 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;
}