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