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