diff --git a/compiler-rt/test/tsan/bench.h b/compiler-rt/test/tsan/bench.h --- a/compiler-rt/test/tsan/bench.h +++ b/compiler-rt/test/tsan/bench.h @@ -1,18 +1,12 @@ -#include -#include -#include -#include -#include +#include "test.h" #include int bench_nthread; int bench_niter; -int grow_clock_var; -pthread_barrier_t glow_clock_barrier; +int bench_mode; void bench(); // defined by user void start_thread_group(int nth, void(*f)(int tid)); -void grow_clock_worker(int tid); int main(int argc, char **argv) { bench_nthread = 2; @@ -21,15 +15,8 @@ bench_niter = 100; if (argc > 2) bench_niter = atoi(argv[2]); - - // Grow thread's clock. - int clock_size = 10; - if (argc > 1) - clock_size = 1000; - pthread_barrier_init(&glow_clock_barrier, 0, clock_size); - start_thread_group(clock_size, grow_clock_worker); - pthread_barrier_destroy(&glow_clock_barrier); - __atomic_load_n(&grow_clock_var, __ATOMIC_ACQUIRE); + if (argc > 3) + bench_mode = atoi(argv[3]); timespec tp0; clock_gettime(CLOCK_MONOTONIC, &tp0); @@ -50,10 +37,3 @@ for (int i = 0; i < nth; i++) pthread_join(th[i], 0); } - -void grow_clock_worker(int tid) { - int res = pthread_barrier_wait(&glow_clock_barrier); - if (res == PTHREAD_BARRIER_SERIAL_THREAD) - __atomic_store_n(&grow_clock_var, 0, __ATOMIC_RELEASE); -} - diff --git a/compiler-rt/test/tsan/bench_memory_access.cpp b/compiler-rt/test/tsan/bench_memory_access.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/tsan/bench_memory_access.cpp @@ -0,0 +1,89 @@ +// RUN: %clangxx_tsan %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s + +// bench.h needs pthread barriers which are not available on OS X +// UNSUPPORTED: darwin + +#include "bench.h" +#include + +void thread(int tid) { + volatile long x = 0; + switch (bench_mode) { + case 0: + for (int i = 0; i < bench_niter; i++) + *(volatile char *)&x = 1; + break; + case 1: + for (int i = 0; i < bench_niter; i++) + *(volatile short *)&x = 1; + break; + case 2: + for (int i = 0; i < bench_niter; i++) + *(volatile int *)&x = 1; + break; + case 3: + for (int i = 0; i < bench_niter; i++) + *(volatile long *)&x = 1; + break; + case 4: + for (int i = 0; i < bench_niter; i++) + *(volatile char *)&x; + break; + case 5: + for (int i = 0; i < bench_niter; i++) + *(volatile short *)&x; + break; + case 6: + for (int i = 0; i < bench_niter; i++) + *(volatile int *)&x; + break; + case 7: + for (int i = 0; i < bench_niter; i++) + *(volatile long *)&x; + case 8: + for (int i = 0; i < bench_niter / 10; i++) { + ((volatile long *)&x)[0]; + ((volatile int *)&x)[0]; + ((volatile short *)&x)[2]; + ((volatile char *)&x)[6]; + ((volatile char *)&x)[7]; + ((volatile long *)&x)[0] = 1; + ((volatile int *)&x)[0] = 1; + ((volatile short *)&x)[2] = 1; + ((volatile char *)&x)[6] = 1; + ((volatile char *)&x)[7] = 1; + } + break; + case 9: { + volatile long size = sizeof(x); + for (int i = 0; i < bench_niter; i++) + memset((void *)&x, i, size); + break; + } + case 10: { + volatile long data[2] = {}; + volatile long size = sizeof(data) - 2; + for (int i = 0; i < bench_niter; i++) + memset(((char *)data) + 1, i, size); + break; + } + case 11: { + volatile long data[2] = {}; + for (int i = 0; i < bench_niter / 8 / 3; i++) { + for (int off = 0; off < 8; off++) { + __sanitizer_unaligned_store16(((char *)data) + off, i); + __sanitizer_unaligned_store32(((char *)data) + off, i); + __sanitizer_unaligned_store64(((char *)data) + off, i); + } + } + break; + } + } +} + +void bench() { + start_thread_group(bench_nthread, thread); +} + +// CHECK: DONE