xref: /llvm-project/compiler-rt/test/tsan/cond_version.c (revision 8aa56d3cc878bf230bb2d732d214deaaadc59af2)
1b8aae540SGreg Fitzgerald // RUN: %clang_tsan -O1 %s -o %t -lrt && %run %t 2>&1 | FileCheck %s
2e6a6183eSAlexey Samsonov // Test that pthread_cond is properly intercepted,
3e6a6183eSAlexey Samsonov // previously there were issues with versioned symbols.
4e6a6183eSAlexey Samsonov // CHECK: OK
5e6a6183eSAlexey Samsonov 
6*8aa56d3cSKuba Brecka // OS X doesn't have pthread_condattr_setclock.
7*8aa56d3cSKuba Brecka // UNSUPPORTED: darwin
8*8aa56d3cSKuba Brecka 
9e6a6183eSAlexey Samsonov #include <stdio.h>
10e6a6183eSAlexey Samsonov #include <stdlib.h>
11e6a6183eSAlexey Samsonov #include <pthread.h>
12e6a6183eSAlexey Samsonov #include <time.h>
13e6a6183eSAlexey Samsonov #include <errno.h>
14e6a6183eSAlexey Samsonov 
main()15e6a6183eSAlexey Samsonov int main() {
16e6a6183eSAlexey Samsonov   typedef unsigned long long u64;
17e6a6183eSAlexey Samsonov   pthread_mutex_t m;
18e6a6183eSAlexey Samsonov   pthread_cond_t c;
19e6a6183eSAlexey Samsonov   pthread_condattr_t at;
20e6a6183eSAlexey Samsonov   struct timespec ts0, ts1, ts2;
21e6a6183eSAlexey Samsonov   int res;
22e6a6183eSAlexey Samsonov   u64 sleep;
23e6a6183eSAlexey Samsonov 
24e6a6183eSAlexey Samsonov   pthread_mutex_init(&m, 0);
25e6a6183eSAlexey Samsonov   pthread_condattr_init(&at);
26e6a6183eSAlexey Samsonov   pthread_condattr_setclock(&at, CLOCK_MONOTONIC);
27e6a6183eSAlexey Samsonov   pthread_cond_init(&c, &at);
28e6a6183eSAlexey Samsonov 
29e6a6183eSAlexey Samsonov   clock_gettime(CLOCK_MONOTONIC, &ts0);
30e6a6183eSAlexey Samsonov   ts1 = ts0;
31e6a6183eSAlexey Samsonov   ts1.tv_sec += 2;
32e6a6183eSAlexey Samsonov 
33e6a6183eSAlexey Samsonov   pthread_mutex_lock(&m);
34e6a6183eSAlexey Samsonov   do {
35e6a6183eSAlexey Samsonov     res = pthread_cond_timedwait(&c, &m, &ts1);
36e6a6183eSAlexey Samsonov   } while (res == 0);
37e6a6183eSAlexey Samsonov   pthread_mutex_unlock(&m);
38e6a6183eSAlexey Samsonov 
39e6a6183eSAlexey Samsonov   clock_gettime(CLOCK_MONOTONIC, &ts2);
40e6a6183eSAlexey Samsonov   sleep = (u64)ts2.tv_sec * 1000000000 + ts2.tv_nsec -
41e6a6183eSAlexey Samsonov       ((u64)ts0.tv_sec * 1000000000 + ts0.tv_nsec);
42e6a6183eSAlexey Samsonov   if (res != ETIMEDOUT)
43e6a6183eSAlexey Samsonov     exit(printf("bad return value %d, want %d\n", res, ETIMEDOUT));
44e6a6183eSAlexey Samsonov   if (sleep < 1000000000)
45e6a6183eSAlexey Samsonov     exit(printf("bad sleep duration %lluns, want %dns\n", sleep, 1000000000));
46e6a6183eSAlexey Samsonov   fprintf(stderr, "OK\n");
47e6a6183eSAlexey Samsonov }
48