1 //===-- tsan_posix.cpp ----------------------------------------------------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //===----------------------------------------------------------------------===//
12 #include "tsan_interface.h"
13 #include "tsan_posix_util.h"
14 #include "tsan_test_util.h"
15 #include "gtest/gtest.h"
23 thread_key(pthread_key_t key
, pthread_mutex_t
*mtx
, int val
, int *cnt
)
31 static void thread_secific_dtor(void *v
) {
32 thread_key
*k
= (thread_key
*)v
;
33 EXPECT_EQ(__interceptor_pthread_mutex_lock(k
->mtx
), 0);
35 __tsan_write4(&k
->cnt
);
36 EXPECT_EQ(__interceptor_pthread_mutex_unlock(k
->mtx
), 0);
39 } else if (k
->val
== 43 || k
->val
== 44) {
41 EXPECT_EQ(pthread_setspecific(k
->key
, k
), 0);
47 static void *dtors_thread(void *p
) {
48 thread_key
*k
= (thread_key
*)p
;
49 EXPECT_EQ(pthread_setspecific(k
->key
, k
), 0);
53 TEST(Posix
, ThreadSpecificDtors
) {
56 EXPECT_EQ(pthread_key_create(&key
, thread_secific_dtor
), 0);
58 EXPECT_EQ(__interceptor_pthread_mutex_init(&mtx
, 0), 0);
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);
73 #if !defined(__aarch64__) && !defined(__APPLE__)
74 static __thread
int local_var
;
76 static void *local_thread(void *p
) {
77 __tsan_write1(&local_var
);
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)),
87 for (int i
= 0; i
< kThreads
; i
++)
88 EXPECT_EQ(__interceptor_pthread_join(th
[i
], 0), 0);
93 TEST(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 is
97 // using malloc and free, which causes false data race reports. On rare
98 // occasions on powerpc64le this test also fails.
99 #if !defined(__aarch64__) && !defined(__APPLE__) && !defined(powerpc64le)
100 local_thread((void*)2);
110 static void *cond_thread(void *p
) {
111 CondContext
&ctx
= *static_cast<CondContext
*>(p
);
113 EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx
.m
), 0);
114 EXPECT_EQ(ctx
.data
, 0);
116 EXPECT_EQ(__interceptor_pthread_cond_signal(&ctx
.c
), 0);
117 EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx
.m
), 0);
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);
124 EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx
.m
), 0);
126 EXPECT_EQ(pthread_cond_broadcast(&ctx
.c
), 0);
127 EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx
.m
), 0);
132 TEST(Posix
, CondBasic
) {
134 EXPECT_EQ(__interceptor_pthread_mutex_init(&ctx
.m
, 0), 0);
135 EXPECT_EQ(__interceptor_pthread_cond_init(&ctx
.c
, 0), 0);
138 EXPECT_EQ(__interceptor_pthread_create(&th
, 0, cond_thread
, &ctx
), 0);
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);
144 EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx
.m
), 0);
145 EXPECT_EQ(pthread_cond_broadcast(&ctx
.c
), 0);
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);
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);