diff options
Diffstat (limited to 'test/tsan/bench.h')
-rw-r--r-- | test/tsan/bench.h | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/test/tsan/bench.h b/test/tsan/bench.h new file mode 100644 index 0000000000000..5ae0dd813db9f --- /dev/null +++ b/test/tsan/bench.h @@ -0,0 +1,59 @@ +#include <pthread.h> +#include <stdlib.h> +#include <stddef.h> +#include <unistd.h> +#include <stdio.h> +#include <time.h> + +int bench_nthread; +int bench_niter; +int grow_clock_var; +pthread_barrier_t glow_clock_barrier; + +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; + if (argc > 1) + bench_nthread = atoi(argv[1]); + 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); + + timespec tp0; + clock_gettime(CLOCK_MONOTONIC, &tp0); + bench(); + timespec tp1; + clock_gettime(CLOCK_MONOTONIC, &tp1); + unsigned long long t = + (tp1.tv_sec * 1000000000ULL + tp1.tv_nsec) - + (tp0.tv_sec * 1000000000ULL + tp0.tv_nsec); + fprintf(stderr, "%llu ns/iter\n", t / bench_niter); + fprintf(stderr, "DONE\n"); +} + +void start_thread_group(int nth, void(*f)(int tid)) { + pthread_t *th = (pthread_t*)malloc(nth * sizeof(pthread_t)); + for (int i = 0; i < nth; i++) + pthread_create(&th[i], 0, (void*(*)(void*))f, (void*)(long)i); + 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); +} + |