brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · ad8b07e Raw
156 lines · cpp
1//===-- tsan_posix.cpp ----------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of ThreadSanitizer (TSan), a race detector.10//11//===----------------------------------------------------------------------===//12#include "tsan_interface.h"13#include "tsan_posix_util.h"14#include "tsan_test_util.h"15#include "gtest/gtest.h"16#include <pthread.h>17 18struct thread_key {19  pthread_key_t key;20  pthread_mutex_t *mtx;21  int val;22  int *cnt;23  thread_key(pthread_key_t key, pthread_mutex_t *mtx, int val, int *cnt)24    : key(key)25    , mtx(mtx)26    , val(val)27    , cnt(cnt) {28  }29};30 31static void thread_secific_dtor(void *v) {32  thread_key *k = (thread_key *)v;33  EXPECT_EQ(__interceptor_pthread_mutex_lock(k->mtx), 0);34  (*k->cnt)++;35  __tsan_write4(&k->cnt);36  EXPECT_EQ(__interceptor_pthread_mutex_unlock(k->mtx), 0);37  if (k->val == 42) {38    // Okay.39  } else if (k->val == 43 || k->val == 44) {40    k->val--;41    EXPECT_EQ(pthread_setspecific(k->key, k), 0);42  } else {43    ASSERT_TRUE(false);44  }45}46 47static void *dtors_thread(void *p) {48  thread_key *k = (thread_key *)p;49  EXPECT_EQ(pthread_setspecific(k->key, k), 0);50  return 0;51}52 53TEST(Posix, ThreadSpecificDtors) {54  int cnt = 0;55  pthread_key_t key;56  EXPECT_EQ(pthread_key_create(&key, thread_secific_dtor), 0);57  pthread_mutex_t mtx;58  EXPECT_EQ(__interceptor_pthread_mutex_init(&mtx, 0), 0);59  pthread_t th[3];60  thread_key k1 = thread_key(key, &mtx, 42, &cnt);61  thread_key k2 = thread_key(key, &mtx, 43, &cnt);62  thread_key k3 = thread_key(key, &mtx, 44, &cnt);63  EXPECT_EQ(__interceptor_pthread_create(&th[0], 0, dtors_thread, &k1), 0);64  EXPECT_EQ(__interceptor_pthread_create(&th[1], 0, dtors_thread, &k2), 0);65  EXPECT_EQ(__interceptor_pthread_join(th[0], 0), 0);66  EXPECT_EQ(__interceptor_pthread_create(&th[2], 0, dtors_thread, &k3), 0);67  EXPECT_EQ(__interceptor_pthread_join(th[1], 0), 0);68  EXPECT_EQ(__interceptor_pthread_join(th[2], 0), 0);69  EXPECT_EQ(pthread_key_delete(key), 0);70  EXPECT_EQ(6, cnt);71}72 73#if !defined(__aarch64__) && !defined(__APPLE__)74static __thread int local_var;75 76static void *local_thread(void *p) {77  __tsan_write1(&local_var);78  __tsan_write1(&p);79  if (p == 0)80    return 0;81  const int kThreads = 4;82  pthread_t th[kThreads];83  for (int i = 0; i < kThreads; i++)84    EXPECT_EQ(__interceptor_pthread_create(&th[i], 0, local_thread,85                                           (void *)((long)p - 1)),86              0);87  for (int i = 0; i < kThreads; i++)88    EXPECT_EQ(__interceptor_pthread_join(th[i], 0), 0);89  return 0;90}91#endif92 93TEST(Posix, ThreadLocalAccesses) {94// The test is failing with high thread count for aarch64.95// FIXME: track down the issue and re-enable the test.96// On Darwin, we're running unit tests without interceptors and __thread is97// using malloc and free, which causes false data race reports.  On rare98// occasions on powerpc64le this test also fails.99#if !defined(__aarch64__) && !defined(__APPLE__) && !defined(powerpc64le)100  local_thread((void*)2);101#endif102}103 104struct CondContext {105  pthread_mutex_t m;106  pthread_cond_t c;107  int data;108};109 110static void *cond_thread(void *p) {111  CondContext &ctx = *static_cast<CondContext*>(p);112 113  EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0);114  EXPECT_EQ(ctx.data, 0);115  ctx.data = 1;116  EXPECT_EQ(__interceptor_pthread_cond_signal(&ctx.c), 0);117  EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0);118 119  EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0);120  while (ctx.data != 2)121    EXPECT_EQ(__interceptor_pthread_cond_wait(&ctx.c, &ctx.m), 0);122  EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0);123 124  EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0);125  ctx.data = 3;126  EXPECT_EQ(pthread_cond_broadcast(&ctx.c), 0);127  EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0);128 129  return 0;130}131 132TEST(Posix, CondBasic) {133  CondContext ctx;134  EXPECT_EQ(__interceptor_pthread_mutex_init(&ctx.m, 0), 0);135  EXPECT_EQ(__interceptor_pthread_cond_init(&ctx.c, 0), 0);136  ctx.data = 0;137  pthread_t th;138  EXPECT_EQ(__interceptor_pthread_create(&th, 0, cond_thread, &ctx), 0);139 140  EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0);141  while (ctx.data != 1)142    EXPECT_EQ(__interceptor_pthread_cond_wait(&ctx.c, &ctx.m), 0);143  ctx.data = 2;144  EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0);145  EXPECT_EQ(pthread_cond_broadcast(&ctx.c), 0);146 147  EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0);148  while (ctx.data != 3)149    EXPECT_EQ(__interceptor_pthread_cond_wait(&ctx.c, &ctx.m), 0);150  EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0);151 152  EXPECT_EQ(__interceptor_pthread_join(th, 0), 0);153  EXPECT_EQ(__interceptor_pthread_cond_destroy(&ctx.c), 0);154  EXPECT_EQ(__interceptor_pthread_mutex_destroy(&ctx.m), 0);155}156