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