Home | History | Annotate | Download | only in tsan
      1 #include <pthread.h>
      2 #include <stdlib.h>
      3 #include <stddef.h>
      4 #include <unistd.h>
      5 #include <stdio.h>
      6 #include <time.h>
      7 
      8 int bench_nthread;
      9 int bench_niter;
     10 int grow_clock_var;
     11 pthread_barrier_t glow_clock_barrier;
     12 
     13 void bench();  // defined by user
     14 void start_thread_group(int nth, void(*f)(int tid));
     15 void grow_clock_worker(int tid);
     16 
     17 int main(int argc, char **argv) {
     18   bench_nthread = 2;
     19   if (argc > 1)
     20     bench_nthread = atoi(argv[1]);
     21   bench_niter = 100;
     22   if (argc > 2)
     23     bench_niter = atoi(argv[2]);
     24 
     25   // Grow thread's clock.
     26   int clock_size = 10;
     27   if (argc > 1)
     28     clock_size = 1000;
     29   pthread_barrier_init(&glow_clock_barrier, 0, clock_size);
     30   start_thread_group(clock_size, grow_clock_worker);
     31   pthread_barrier_destroy(&glow_clock_barrier);
     32   __atomic_load_n(&grow_clock_var, __ATOMIC_ACQUIRE);
     33 
     34   timespec tp0;
     35   clock_gettime(CLOCK_MONOTONIC, &tp0);
     36   bench();
     37   timespec tp1;
     38   clock_gettime(CLOCK_MONOTONIC, &tp1);
     39   unsigned long long t =
     40       (tp1.tv_sec * 1000000000ULL + tp1.tv_nsec) -
     41       (tp0.tv_sec * 1000000000ULL + tp0.tv_nsec);
     42   fprintf(stderr, "%llu ns/iter\n", t / bench_niter);
     43   fprintf(stderr, "DONE\n");
     44 }
     45 
     46 void start_thread_group(int nth, void(*f)(int tid)) {
     47   pthread_t *th = (pthread_t*)malloc(nth * sizeof(pthread_t));
     48   for (int i = 0; i < nth; i++)
     49     pthread_create(&th[i], 0, (void*(*)(void*))f, (void*)(long)i);
     50   for (int i = 0; i < nth; i++)
     51     pthread_join(th[i], 0);
     52 }
     53 
     54 void grow_clock_worker(int tid) {
     55   int res = pthread_barrier_wait(&glow_clock_barrier);
     56   if (res == PTHREAD_BARRIER_SERIAL_THREAD)
     57     __atomic_store_n(&grow_clock_var, 0, __ATOMIC_RELEASE);
     58 }
     59 
     60